diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java index e843aec..69f861c 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java @@ -1,17 +1,15 @@ /* * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 遵循 Apache 许可证 2.0 版("许可证"); + * 除非遵守许可证,否则不得使用本文件。 + * 您可以在以下网址获取许可证副本: * * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 除非适用法律要求或书面同意,根据许可证分发的软件 + * 按"原样"分发,不附带任何明示或暗示的保证或条件。 + * 请参阅许可证,了解管理权限和限制的具体语言。 */ package net.micode.notes.ui; @@ -78,93 +76,91 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashSet; +/** + * 笔记列表活动类,负责展示笔记和文件夹列表,处理用户交互(如新建、删除、移动笔记等) + * 实现了列表项点击、长按等事件处理接口 + */ public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { - private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; - - private static final int FOLDER_LIST_QUERY_TOKEN = 1; - - private static final int MENU_FOLDER_DELETE = 0; - - private static final int MENU_FOLDER_VIEW = 1; - - private static final int MENU_FOLDER_CHANGE_NAME = 2; - - private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; - + private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; // 文件夹笔记列表查询标记 + private static final int FOLDER_LIST_QUERY_TOKEN = 1; // 文件夹列表查询标记 + private static final int MENU_FOLDER_DELETE = 0; // 文件夹删除菜单项ID + private static final int MENU_FOLDER_VIEW = 1; // 文件夹查看菜单项ID + private static final int MENU_FOLDER_CHANGE_NAME = 2; // 文件夹重命名菜单项ID + private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; // 首次使用引导标记的SharedPreferences键 + + /** + * 列表编辑状态枚举: + * NOTE_LIST - 根笔记列表状态 + * SUB_FOLDER - 子文件夹状态 + * CALL_RECORD_FOLDER - 通话记录文件夹状态 + */ private enum ListEditState { NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER }; - private ListEditState mState; - - private BackgroundQueryHandler mBackgroundQueryHandler; - - private NotesListAdapter mNotesListAdapter; - - private ListView mNotesListView; - - private Button mAddNewNote; - - private boolean mDispatch; - - private int mOriginY; - - private int mDispatchY; - - private TextView mTitleBar; - - private long mCurrentFolderId; - - private ContentResolver mContentResolver; - - private ModeCallback mModeCallBack; - - private static final String TAG = "NotesListActivity"; - - public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; - - private NoteItemData mFocusNoteDataItem; - - private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; - + private ListEditState mState; // 当前列表编辑状态 + private BackgroundQueryHandler mBackgroundQueryHandler; // 后台查询处理器,用于异步数据库查询 + private NotesListAdapter mNotesListAdapter; // 笔记列表适配器 + private ListView mNotesListView; // 笔记列表视图 + private Button mAddNewNote; // 新建笔记按钮 + private boolean mDispatch; // 触摸事件分发标记 + private int mOriginY; // 触摸事件原始Y坐标 + private int mDispatchY; // 分发事件的Y坐标 + private TextView mTitleBar; // 标题栏文本视图 + private long mCurrentFolderId; // 当前文件夹ID,默认根文件夹 + private ContentResolver mContentResolver; // 内容解析器,用于操作数据提供者 + private ModeCallback mModeCallBack; // 多选模式回调处理器 + private static final String TAG = "NotesListActivity"; // 日志标签 + public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; // 列表滚动速率 + private NoteItemData mFocusNoteDataItem; // 当前聚焦的笔记/文件夹数据项 + + // 查询条件常量 + private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; // 普通查询:子项属于某个父文件夹 private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " - + NoteColumns.NOTES_COUNT + ">0)"; + + NoteColumns.NOTES_COUNT + ">0)"; // 根文件夹查询:排除系统类型或包含有内容的通话记录文件夹 - private final static int REQUEST_CODE_OPEN_NODE = 102; - private final static int REQUEST_CODE_NEW_NODE = 103; + private final static int REQUEST_CODE_OPEN_NODE = 102; // 打开节点(笔记/文件夹)请求码 + private final static int REQUEST_CODE_NEW_NODE = 103; // 新建节点请求码 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.note_list); - initResources(); + setContentView(R.layout.note_list); // 加载笔记列表布局 + initResources(); // 初始化资源和视图组件 /** - * Insert an introduction when user firstly use this application + * 首次使用应用时插入引导笔记 */ - setAppInfoFromRawRes(); + setAppInfoFromRawRes(); // 从原始资源读取引导内容并保存为笔记 } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // 处理子活动返回结果,刷新列表数据 if (resultCode == RESULT_OK && (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) { - mNotesListAdapter.changeCursor(null); + mNotesListAdapter.changeCursor(null); // 刷新适配器数据 } else { super.onActivityResult(requestCode, resultCode, data); } } + /** + * 从原始资源文件读取引导内容并保存为笔记 + */ private void setAppInfoFromRawRes() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + // 检查是否已显示过引导 if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { StringBuilder sb = new StringBuilder(); InputStream in = null; try { - in = getResources().openRawResource(R.raw.introduction); + // 打开引导内容资源文件 + in = getResources().openRawResource(R.raw.introduction); if (in != null) { + // 读取文本内容 InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); char [] buf = new char[1024]; @@ -180,21 +176,23 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt e.printStackTrace(); return; } finally { + // 关闭输入流 if(in != null) { try { in.close(); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } } } + // 创建引导笔记并保存 WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER, AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE, ResourceParser.RED); note.setWorkingText(sb.toString()); if (note.saveNote()) { + // 标记已显示引导 sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit(); } else { Log.e(TAG, "Save introduction note error"); @@ -206,138 +204,154 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override protected void onStart() { super.onStart(); - startAsyncNotesListQuery(); + startAsyncNotesListQuery(); // 启动异步查询加载笔记列表数据 } + /** + * 初始化资源和视图组件 + */ private void initResources() { - mContentResolver = this.getContentResolver(); - mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver()); - mCurrentFolderId = Notes.ID_ROOT_FOLDER; - mNotesListView = (ListView) findViewById(R.id.notes_list); + mContentResolver = this.getContentResolver(); // 获取内容解析器 + mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver()); // 创建后台查询处理器 + mCurrentFolderId = Notes.ID_ROOT_FOLDER; // 默认显示根文件夹 + mNotesListView = (ListView) findViewById(R.id.notes_list); // 获取列表视图 + // 添加列表页脚视图 mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null), null, false); + // 设置列表项点击监听器 mNotesListView.setOnItemClickListener(new OnListItemClickListener()); + // 设置列表项长按监听器(当前活动自身处理) mNotesListView.setOnItemLongClickListener(this); - mNotesListAdapter = new NotesListAdapter(this); - mNotesListView.setAdapter(mNotesListAdapter); - mAddNewNote = (Button) findViewById(R.id.btn_new_note); - mAddNewNote.setOnClickListener(this); - mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); - mDispatch = false; + mNotesListAdapter = new NotesListAdapter(this); // 创建列表适配器 + mNotesListView.setAdapter(mNotesListAdapter); // 设置适配器 + mAddNewNote = (Button) findViewById(R.id.btn_new_note); // 获取新建笔记按钮 + mAddNewNote.setOnClickListener(this); // 设置点击监听器 + mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); // 设置触摸事件监听器,处理透明区域点击分发 + mDispatch = false; // 初始化事件分发标记 mDispatchY = 0; mOriginY = 0; - mTitleBar = (TextView) findViewById(R.id.tv_title_bar); - mState = ListEditState.NOTE_LIST; - mModeCallBack = new ModeCallback(); + mTitleBar = (TextView) findViewById(R.id.tv_title_bar); // 获取标题栏视图 + mState = ListEditState.NOTE_LIST; // 初始状态为根笔记列表 + mModeCallBack = new ModeCallback(); // 创建多选模式回调对象 } + /** + * 多选模式回调处理类,实现ListView.MultiChoiceModeListener和菜单项点击处理 + */ private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener { - private DropdownMenu mDropDownMenu; - private ActionMode mActionMode; - private MenuItem mMoveMenu; + private DropdownMenu mDropDownMenu; // 下拉菜单组件 + private ActionMode mActionMode; // 多选模式操作栏 + /** + * 创建多选模式操作栏时调用,加载菜单布局并设置菜单项点击监听器 + */ public boolean onCreateActionMode(ActionMode mode, Menu menu) { - getMenuInflater().inflate(R.menu.note_list_options, menu); - menu.findItem(R.id.delete).setOnMenuItemClickListener(this); - mMoveMenu = menu.findItem(R.id.move); + getMenuInflater().inflate(R.menu.note_list_options, menu); // 加载操作栏菜单布局 + menu.findItem(R.id.delete).setOnMenuItemClickListener(this); // 设置删除菜单项点击监听器 + mMoveMenu = menu.findItem(R.id.move); // 获取移动菜单项 + + // 根据当前文件夹类型和用户文件夹数量判断移动菜单项是否可见 if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER || DataUtils.getUserFolderCount(mContentResolver) == 0) { mMoveMenu.setVisible(false); } else { mMoveMenu.setVisible(true); - mMoveMenu.setOnMenuItemClickListener(this); + mMoveMenu.setOnMenuItemClickListener(this); // 设置移动菜单项点击监听器 } - mActionMode = mode; - mNotesListAdapter.setChoiceMode(true); - mNotesListView.setLongClickable(false); - mAddNewNote.setVisibility(View.GONE); + mActionMode = mode; // 保存操作栏实例 + mNotesListAdapter.setChoiceMode(true); // 启用列表项多选模式 + mNotesListView.setLongClickable(false); // 禁用长按事件(避免与多选模式冲突) + mAddNewNote.setVisibility(View.GONE); // 隐藏新建笔记按钮 + + // 设置操作栏自定义视图(下拉菜单) View customView = LayoutInflater.from(NotesListActivity.this).inflate( R.layout.note_list_dropdown_menu, null); mode.setCustomView(customView); mDropDownMenu = new DropdownMenu(NotesListActivity.this, (Button) customView.findViewById(R.id.selection_menu), R.menu.note_list_dropdown); + // 设置下拉菜单点击监听器(全选/反选) mDropDownMenu.setOnDropdownMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){ public boolean onMenuItemClick(MenuItem item) { - mNotesListAdapter.selectAll(!mNotesListAdapter.isAllSelected()); - updateMenu(); + mNotesListAdapter.selectAll(!mNotesListAdapter.isAllSelected()); // 切换全选状态 + updateMenu(); // 更新菜单显示 return true; } - }); return true; } + /** + * 更新菜单显示状态(选中项数量、全选/反选文本) + */ private void updateMenu() { - int selectedCount = mNotesListAdapter.getSelectedCount(); - // Update dropdown menu + int selectedCount = mNotesListAdapter.getSelectedCount(); // 获取选中项数量 + // 更新下拉菜单标题 String format = getResources().getString(R.string.menu_select_title, selectedCount); mDropDownMenu.setTitle(format); + // 更新全选菜单项状态 MenuItem item = mDropDownMenu.findItem(R.id.action_select_all); if (item != null) { if (mNotesListAdapter.isAllSelected()) { item.setChecked(true); - item.setTitle(R.string.menu_deselect_all); + item.setTitle(R.string.menu_deselect_all); // 显示反选文本 } else { item.setChecked(false); - item.setTitle(R.string.menu_select_all); + item.setTitle(R.string.menu_select_all); // 显示全选文本 } } } - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - // TODO Auto-generated method stub - return false; - } - - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - // TODO Auto-generated method stub - return false; - } - + // 以下为ListView.MultiChoiceModeListener接口的默认实现(未使用的方法) + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; } public void onDestroyActionMode(ActionMode mode) { - mNotesListAdapter.setChoiceMode(false); - mNotesListView.setLongClickable(true); - mAddNewNote.setVisibility(View.VISIBLE); + // 销毁操作栏时恢复列表状态 + mNotesListAdapter.setChoiceMode(false); // 禁用多选模式 + mNotesListView.setLongClickable(true); // 重新启用长按事件 + mAddNewNote.setVisibility(View.VISIBLE); // 显示新建笔记按钮 } + public void finishActionMode() { mActionMode.finish(); } // 结束操作栏 - public void finishActionMode() { - mActionMode.finish(); - } - - public void onItemCheckedStateChanged(ActionMode mode, int position, long id, - boolean checked) { - mNotesListAdapter.setCheckedItem(position, checked); - updateMenu(); + /** + * 列表项选中状态变化时调用,更新选中状态和菜单显示 + */ + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { + mNotesListAdapter.setCheckedItem(position, checked); // 更新适配器中的选中状态 + updateMenu(); // 更新菜单显示 } + /** + * 处理操作栏菜单项点击事件(删除、移动) + */ public boolean onMenuItemClick(MenuItem item) { if (mNotesListAdapter.getSelectedCount() == 0) { + // 无选中项时提示用户 Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none), Toast.LENGTH_SHORT).show(); return true; } switch (item.getItemId()) { - case R.id.delete: + case R.id.delete: // 删除菜单项 + // 显示删除确认对话框 AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); builder.setTitle(getString(R.string.alert_title_delete)); builder.setIcon(android.R.drawable.ic_dialog_alert); builder.setMessage(getString(R.string.alert_message_delete_notes, - mNotesListAdapter.getSelectedCount())); + mNotesListAdapter.getSelectedCount())); // 显示删除数量提示 builder.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - batchDelete(); - } - }); + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + batchDelete(); // 执行批量删除操作 + } + }); builder.setNegativeButton(android.R.string.cancel, null); builder.show(); break; - case R.id.move: - startQueryDestinationFolders(); + case R.id.move: // 移动菜单项 + startQueryDestinationFolders(); // 启动目标文件夹查询 break; default: return false; @@ -346,37 +360,36 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 新建笔记按钮触摸事件监听器,处理透明区域的事件分发 + */ private class NewNoteOnTouchListener implements OnTouchListener { public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: { + case MotionEvent.ACTION_DOWN: { // 按下事件 Display display = getWindowManager().getDefaultDisplay(); int screenHeight = display.getHeight(); int newNoteViewHeight = mAddNewNote.getHeight(); - int start = screenHeight - newNoteViewHeight; - int eventY = start + (int) event.getY(); - /** - * Minus TitleBar's height - */ + int start = screenHeight - newNoteViewHeight; // 按钮底部Y坐标 + int eventY = start + (int) event.getY(); // 事件在屏幕中的Y坐标 + + // 根据当前状态调整坐标(子文件夹状态需减去标题栏高度) if (mState == ListEditState.SUB_FOLDER) { eventY -= mTitleBar.getHeight(); start -= mTitleBar.getHeight(); } + /** - * HACKME:When click the transparent part of "New Note" button, dispatch - * the event to the list view behind this button. The transparent part of - * "New Note" button could be expressed by formula y=-0.12x+94(Unit:pixel) - * and the line top of the button. The coordinate based on left of the "New - * Note" button. The 94 represents maximum height of the transparent part. - * Notice that, if the background of the button changes, the formula should - * also change. This is very bad, just for the UI designer's strong requirement. + * 处理按钮透明区域的点击事件分发: + * 透明区域由公式 y = -0.12x + 94(基于按钮左顶点的坐标系统)和按钮顶部边界定义 + * 当点击位置在透明区域内时,将事件分发到列表视图以触发滚动或点击操作 */ if (event.getY() < (event.getX() * (-0.12) + 94)) { View view = mNotesListView.getChildAt(mNotesListView.getChildCount() - 1 - - mNotesListView.getFooterViewsCount()); - if (view != null && view.getBottom() > start - && (view.getTop() < (start + 94))) { + - mNotesListView.getFooterViewsCount()); // 获取最后一个可见列表项 + if (view != null && view.getBottom() > start && (view.getTop() < (start + 94))) { + // 保存原始坐标并调整事件坐标,触发列表视图的事件分发 mOriginY = (int) event.getY(); mDispatchY = eventY; event.setLocation(event.getX(), mDispatchY); @@ -386,15 +399,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } break; } - case MotionEvent.ACTION_MOVE: { + case MotionEvent.ACTION_MOVE: { // 移动事件,继续分发 if (mDispatch) { - mDispatchY += (int) event.getY() - mOriginY; + mDispatchY += (int) event.getY() - mOriginY; // 更新分发坐标 event.setLocation(event.getX(), mDispatchY); return mNotesListView.dispatchTouchEvent(event); } break; } - default: { + default: { // 其他事件(抬起、取消等),结束分发 if (mDispatch) { event.setLocation(event.getX(), mDispatchY); mDispatch = false; @@ -408,15 +421,23 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }; + /** + * 启动异步查询加载笔记列表数据 + */ private void startAsyncNotesListQuery() { + // 根据当前文件夹ID构建查询条件 String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION : NORMAL_SELECTION; + // 执行异步查询(背景线程处理数据库操作) mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null, Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] { - String.valueOf(mCurrentFolderId) - }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); + String.valueOf(mCurrentFolderId) + }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); // 按类型降序、修改时间降序排序 } + /** + * 后台查询处理器,处理查询结果回调 + */ private final class BackgroundQueryHandler extends AsyncQueryHandler { public BackgroundQueryHandler(ContentResolver contentResolver) { super(contentResolver); @@ -425,12 +446,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { switch (token) { - case FOLDER_NOTE_LIST_QUERY_TOKEN: - mNotesListAdapter.changeCursor(cursor); + case FOLDER_NOTE_LIST_QUERY_TOKEN: // 笔记列表查询结果 + mNotesListAdapter.changeCursor(cursor); // 更新适配器数据 break; - case FOLDER_LIST_QUERY_TOKEN: + case FOLDER_LIST_QUERY_TOKEN: // 文件夹列表查询结果 if (cursor != null && cursor.getCount() > 0) { - showFolderListMenu(cursor); + showFolderListMenu(cursor); // 显示目标文件夹选择菜单 } else { Log.e(TAG, "Query folder failed"); } @@ -441,48 +462,62 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 显示目标文件夹选择菜单,用于移动笔记操作 + */ private void showFolderListMenu(Cursor cursor) { AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); - builder.setTitle(R.string.menu_title_select_folder); - final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor); + builder.setTitle(R.string.menu_title_select_folder); // 设置对话框标题 + final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor); // 创建文件夹列表适配器 + // 设置列表项点击监听器(执行移动操作) builder.setAdapter(adapter, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { + // 批量移动选中笔记到目标文件夹 DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which)); + // 显示成功提示 Toast.makeText( NotesListActivity.this, getString(R.string.format_move_notes_to_folder, mNotesListAdapter.getSelectedCount(), adapter.getFolderName(NotesListActivity.this, which)), Toast.LENGTH_SHORT).show(); - mModeCallBack.finishActionMode(); + mModeCallBack.finishActionMode(); // 结束多选模式 } }); - builder.show(); + builder.show(); // 显示对话框 } + /** + * 创建新笔记,启动笔记编辑活动 + */ private void createNewNote() { Intent intent = new Intent(this, NoteEditActivity.class); - intent.setAction(Intent.ACTION_INSERT_OR_EDIT); - intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); - this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); // 操作类型:插入或编辑 + intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); // 传递当前文件夹ID + this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); // 启动活动并等待结果 } + /** + * 批量删除选中的笔记或文件夹(异步任务处理) + */ private void batchDelete() { new AsyncTask>() { + /** + * 后台执行删除操作,返回关联的桌面小部件信息 + */ protected HashSet doInBackground(Void... unused) { - HashSet widgets = mNotesListAdapter.getSelectedWidget(); + HashSet widgets = mNotesListAdapter.getSelectedWidget(); // 获取选中项关联的小部件 + if (!isSyncMode()) { - // if not synced, delete notes directly + // 非同步模式:直接删除 if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter .getSelectedItemIds())) { } else { Log.e(TAG, "Delete notes error, should not happens"); } } else { - // in sync mode, we'll move the deleted note into the trash - // folder + // 同步模式:移动到回收站文件夹 if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { Log.e(TAG, "Move notes to trash folder error, should not happens"); @@ -491,39 +526,51 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return widgets; } + /** + * 处理删除后的操作(更新小部件) + */ @Override protected void onPostExecute(HashSet widgets) { if (widgets != null) { + // 遍历更新所有关联的桌面小部件 for (AppWidgetAttribute widget : widgets) { if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { - updateWidget(widget.widgetId, widget.widgetType); + updateWidget(widget.widgetId, widget.widgetType); // 更新小部件显示 } } } - mModeCallBack.finishActionMode(); + mModeCallBack.finishActionMode(); // 结束多选模式 } }.execute(); } + /** + * 删除指定文件夹(包括其下所有内容) + */ private void deleteFolder(long folderId) { if (folderId == Notes.ID_ROOT_FOLDER) { + // 不能删除根文件夹 Log.e(TAG, "Wrong folder id, should not happen " + folderId); return; } HashSet ids = new HashSet(); - ids.add(folderId); + ids.add(folderId); // 添加要删除的文件夹ID + // 获取文件夹内笔记关联的小部件 HashSet widgets = DataUtils.getFolderNoteWidget(mContentResolver, folderId); + if (!isSyncMode()) { - // if not synced, delete folder directly + // 非同步模式:直接删除 DataUtils.batchDeleteNotes(mContentResolver, ids); } else { - // in sync mode, we'll move the deleted folder into the trash folder + // 同步模式:移动到回收站 DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_TRASH_FOLER); } + if (widgets != null) { + // 更新关联的小部件 for (AppWidgetAttribute widget : widgets) { if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { @@ -533,154 +580,175 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 打开笔记节点(查看或编辑笔记) + */ private void openNode(NoteItemData data) { Intent intent = new Intent(this, NoteEditActivity.class); - intent.setAction(Intent.ACTION_VIEW); - intent.putExtra(Intent.EXTRA_UID, data.getId()); - this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); + intent.setAction(Intent.ACTION_VIEW); // 操作类型:查看 + intent.putExtra(Intent.EXTRA_UID, data.getId()); // 传递笔记ID + this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); // 启动活动并等待结果 } + /** + * 打开文件夹,切换到子文件夹视图 + */ private void openFolder(NoteItemData data) { - mCurrentFolderId = data.getId(); - startAsyncNotesListQuery(); + mCurrentFolderId = data.getId(); // 更新当前文件夹ID + startAsyncNotesListQuery(); // 加载子文件夹内容 + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { - mState = ListEditState.CALL_RECORD_FOLDER; - mAddNewNote.setVisibility(View.GONE); + mState = ListEditState.CALL_RECORD_FOLDER; // 设置为通话记录文件夹状态 + mAddNewNote.setVisibility(View.GONE); // 隐藏新建笔记按钮 } else { - mState = ListEditState.SUB_FOLDER; + mState = ListEditState.SUB_FOLDER; // 设置为子文件夹状态 } + + // 更新标题栏显示 if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { - mTitleBar.setText(R.string.call_record_folder_name); + mTitleBar.setText(R.string.call_record_folder_name); // 通话记录文件夹标题 } else { - mTitleBar.setText(data.getSnippet()); + mTitleBar.setText(data.getSnippet()); // 显示文件夹名称 } - mTitleBar.setVisibility(View.VISIBLE); + mTitleBar.setVisibility(View.VISIBLE); // 显示标题栏 } + /** + * 视图点击事件处理(主要处理新建笔记按钮点击) + */ public void onClick(View v) { switch (v.getId()) { - case R.id.btn_new_note: - createNewNote(); + case R.id.btn_new_note: // 新建笔记按钮 + createNewNote(); // 调用新建笔记方法 break; default: break; } } + /** + * 显示软键盘 + */ private void showSoftInput() { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (inputMethodManager != null) { - inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // 强制显示软键盘 } } + /** + * 隐藏软键盘 + */ private void hideSoftInput(View view) { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); + inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); // 隐藏指定视图的软键盘 } + /** + * 显示创建或修改文件夹对话框 + * @param create 是否为创建模式(true=创建新文件夹,false=修改现有文件夹) + */ private void showCreateOrModifyFolderDialog(final boolean create) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); - View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null); - final EditText etName = (EditText) view.findViewById(R.id.et_foler_name); - showSoftInput(); + View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null); // 加载输入对话框布局 + final EditText etName = (EditText) view.findViewById(R.id.et_foler_name); // 获取名称输入框 + showSoftInput(); // 显示软键盘 + if (!create) { + // 修改模式:填充现有文件夹名称 if (mFocusNoteDataItem != null) { etName.setText(mFocusNoteDataItem.getSnippet()); - builder.setTitle(getString(R.string.menu_folder_change_name)); + builder.setTitle(getString(R.string.menu_folder_change_name)); // 设置标题为"重命名" } else { Log.e(TAG, "The long click data item is null"); return; } } else { + // 创建模式:清空输入框 etName.setText(""); - builder.setTitle(this.getString(R.string.menu_create_folder)); + builder.setTitle(this.getString(R.string.menu_create_folder)); // 设置标题为"新建文件夹" } - builder.setPositiveButton(android.R.string.ok, null); + builder.setPositiveButton(android.R.string.ok, null); // 初始时不设置点击监听器,防止空值提交 builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - hideSoftInput(etName); + hideSoftInput(etName); // 隐藏软键盘 } }); - final Dialog dialog = builder.setView(view).show(); - final Button positive = (Button)dialog.findViewById(android.R.id.button1); + final Dialog dialog = builder.setView(view).show(); // 显示对话框 + final Button positive = (Button)dialog.findViewById(android.R.id.button1); // 获取确定按钮 + + // 确定按钮点击监听器(处理名称验证和保存) positive.setOnClickListener(new OnClickListener() { public void onClick(View v) { - hideSoftInput(etName); - String name = etName.getText().toString(); + hideSoftInput(etName); // 隐藏软键盘 + String name = etName.getText().toString(); // 获取输入的名称 + + // 检查文件夹名称是否已存在 if (DataUtils.checkVisibleFolderName(mContentResolver, name)) { Toast.makeText(NotesListActivity.this, getString(R.string.folder_exist, name), Toast.LENGTH_LONG).show(); - etName.setSelection(0, etName.length()); + etName.setSelection(0, etName.length()); // 选中全部文本以便修改 return; } + if (!create) { + // 修改模式:更新文件夹名称 if (!TextUtils.isEmpty(name)) { ContentValues values = new ContentValues(); - values.put(NoteColumns.SNIPPET, name); - values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); - values.put(NoteColumns.LOCAL_MODIFIED, 1); + values.put(NoteColumns.SNIPPET, name); // 设置新名称 + values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); // 类型为文件夹 + values.put(NoteColumns.LOCAL_MODIFIED, 1); // 标记本地修改 mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID + "=?", new String[] { - String.valueOf(mFocusNoteDataItem.getId()) + String.valueOf(mFocusNoteDataItem.getId()) }); } } else if (!TextUtils.isEmpty(name)) { + // 创建模式:插入新文件夹 ContentValues values = new ContentValues(); values.put(NoteColumns.SNIPPET, name); values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); - mContentResolver.insert(Notes.CONTENT_NOTE_URI, values); + mContentResolver.insert(Notes.CONTENT_NOTE_URI, values); // 插入到内容提供者 } - dialog.dismiss(); + dialog.dismiss(); // 关闭对话框 } }); + // 输入框内容变化监听器(控制确定按钮是否可用) if (TextUtils.isEmpty(etName.getText())) { positive.setEnabled(false); } - /** - * When the name edit text is null, disable the positive button - */ etName.addTextChangedListener(new TextWatcher() { - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - // TODO Auto-generated method stub - - } + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void onTextChanged(CharSequence s, int start, int before, int count) { - if (TextUtils.isEmpty(etName.getText())) { - positive.setEnabled(false); - } else { - positive.setEnabled(true); - } + positive.setEnabled(!TextUtils.isEmpty(etName.getText())); // 非空时启用按钮 } - public void afterTextChanged(Editable s) { - // TODO Auto-generated method stub - - } + public void afterTextChanged(Editable s) {} }); } @Override public void onBackPressed() { + // 处理返回键逻辑,根据当前状态切换视图 switch (mState) { - case SUB_FOLDER: + case SUB_FOLDER: // 子文件夹状态:返回根目录 mCurrentFolderId = Notes.ID_ROOT_FOLDER; mState = ListEditState.NOTE_LIST; - startAsyncNotesListQuery(); - mTitleBar.setVisibility(View.GONE); + startAsyncNotesListQuery(); // 重新加载根目录内容 + mTitleBar.setVisibility(View.GONE); // 隐藏标题栏 break; - case CALL_RECORD_FOLDER: + case CALL_RECORD_FOLDER: // 通话记录文件夹状态:返回根目录 mCurrentFolderId = Notes.ID_ROOT_FOLDER; mState = ListEditState.NOTE_LIST; - mAddNewNote.setVisibility(View.VISIBLE); + mAddNewNote.setVisibility(View.VISIBLE); // 显示新建按钮 mTitleBar.setVisibility(View.GONE); startAsyncNotesListQuery(); break; - case NOTE_LIST: + case NOTE_LIST: // 根目录状态:调用系统返回逻辑 super.onBackPressed(); break; default: @@ -688,8 +756,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 更新桌面小部件显示 + * @param appWidgetId 小部件ID + * @param appWidgetType 小部件类型(2x或4x) + */ private void updateWidget(int appWidgetId, int appWidgetType) { - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); // 小部件更新意图 + + // 根据类型设置目标组件 if (appWidgetType == Notes.TYPE_WIDGET_2X) { intent.setClass(this, NoteWidgetProvider_2x.class); } else if (appWidgetType == Notes.TYPE_WIDGET_4X) { @@ -699,18 +774,20 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return; } - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { - appWidgetId - }); - - sendBroadcast(intent); - setResult(RESULT_OK, intent); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { appWidgetId }); // 传递小部件ID + sendBroadcast(intent); // 发送广播更新小部件 + setResult(RESULT_OK, intent); // 设置活动结果 } + /** + * 文件夹长按上下文菜单创建监听器 + */ private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (mFocusNoteDataItem != null) { + // 设置菜单标题为文件夹名称 menu.setHeaderTitle(mFocusNoteDataItem.getSnippet()); + // 添加查看、删除、重命名菜单项 menu.add(0, MENU_FOLDER_VIEW, 0, R.string.menu_folder_view); menu.add(0, MENU_FOLDER_DELETE, 0, R.string.menu_folder_delete); menu.add(0, MENU_FOLDER_CHANGE_NAME, 0, R.string.menu_folder_change_name); @@ -721,7 +798,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override public void onContextMenuClosed(Menu menu) { if (mNotesListView != null) { - mNotesListView.setOnCreateContextMenuListener(null); + mNotesListView.setOnCreateContextMenuListener(null); // 清除上下文菜单监听器 } super.onContextMenuClosed(menu); } @@ -732,46 +809,48 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt Log.e(TAG, "The long click data item is null"); return false; } + // 处理上下文菜单项点击事件(查看、删除、重命名文件夹) switch (item.getItemId()) { - case MENU_FOLDER_VIEW: + case MENU_FOLDER_VIEW: // 查看文件夹 openFolder(mFocusNoteDataItem); break; - case MENU_FOLDER_DELETE: + case MENU_FOLDER_DELETE: // 删除文件夹 + // 显示删除确认对话框 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.alert_title_delete)); builder.setIcon(android.R.drawable.ic_dialog_alert); - builder.setMessage(getString(R.string.alert_message_delete_folder)); + builder.setMessage(getString(R.string.alert_message_delete_folder)); // 删除文件夹提示 builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - deleteFolder(mFocusNoteDataItem.getId()); + deleteFolder(mFocusNoteDataItem.getId()); // 执行删除操作 } }); builder.setNegativeButton(android.R.string.cancel, null); builder.show(); break; - case MENU_FOLDER_CHANGE_NAME: - showCreateOrModifyFolderDialog(false); + case MENU_FOLDER_CHANGE_NAME: // 重命名文件夹 + showCreateOrModifyFolderDialog(false); // 显示修改对话框 break; default: break; } - return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { - menu.clear(); + menu.clear(); // 清空菜单 + // 根据当前状态加载不同的菜单布局 if (mState == ListEditState.NOTE_LIST) { - getMenuInflater().inflate(R.menu.note_list, menu); - // set sync or sync_cancel + getMenuInflater().inflate(R.menu.note_list, menu); // 根目录菜单 + // 更新同步菜单项文本(显示"同步"或"取消同步") menu.findItem(R.id.menu_sync).setTitle( GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync); } else if (mState == ListEditState.SUB_FOLDER) { - getMenuInflater().inflate(R.menu.sub_folder, menu); + getMenuInflater().inflate(R.menu.sub_folder, menu); // 子文件夹菜单 } else if (mState == ListEditState.CALL_RECORD_FOLDER) { - getMenuInflater().inflate(R.menu.call_record_folder, menu); + getMenuInflater().inflate(R.menu.call_record_folder, menu); // 通话记录文件夹菜单 } else { Log.e(TAG, "Wrong state:" + mState); } @@ -780,36 +859,38 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override public boolean onOptionsItemSelected(MenuItem item) { + // 处理选项菜单点击事件 switch (item.getItemId()) { - case R.id.menu_new_folder: { - showCreateOrModifyFolderDialog(true); + case R.id.menu_new_folder: { // 新建文件夹 + showCreateOrModifyFolderDialog(true); // 显示创建对话框 break; } - case R.id.menu_export_text: { - exportNoteToText(); + case R.id.menu_export_text: { // 导出笔记为文本 + exportNoteToText(); // 执行导出操作 break; } - case R.id.menu_sync: { + case R.id.menu_sync: { // 同步操作 if (isSyncMode()) { + // 根据当前同步状态切换操作(开始/取消同步) if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) { GTaskSyncService.startSync(this); } else { GTaskSyncService.cancelSync(this); } } else { - startPreferenceActivity(); + startPreferenceActivity(); // 启动设置活动配置同步账户 } break; } - case R.id.menu_setting: { + case R.id.menu_setting: { // 打开设置 startPreferenceActivity(); break; } - case R.id.menu_new_note: { + case R.id.menu_new_note: { // 新建笔记(选项菜单中的入口) createNewNote(); break; } - case R.id.menu_search: + case R.id.menu_search: // 搜索笔记 onSearchRequested(); break; default: @@ -820,91 +901,99 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override public boolean onSearchRequested() { - startSearch(null, false, null /* appData */, false); + startSearch(null, false, null /* appData */, false); // 启动系统搜索功能 return true; } + /** + * 导出笔记为文本文件(异步任务处理) + */ private void exportNoteToText() { - final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this); + final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this); // 获取备份工具实例 new AsyncTask() { @Override protected Integer doInBackground(Void... unused) { - return backup.exportToText(); + return backup.exportToText(); // 执行导出操作并返回状态码 } @Override protected void onPostExecute(Integer result) { + // 根据导出结果显示相应提示对话框 if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) { - AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); - builder.setTitle(NotesListActivity.this - .getString(R.string.failed_sdcard_export)); - builder.setMessage(NotesListActivity.this - .getString(R.string.error_sdcard_unmounted)); - builder.setPositiveButton(android.R.string.ok, null); - builder.show(); + showExportResultDialog(R.string.failed_sdcard_export, R.string.error_sdcard_unmounted); } else if (result == BackupUtils.STATE_SUCCESS) { - AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); - builder.setTitle(NotesListActivity.this - .getString(R.string.success_sdcard_export)); - builder.setMessage(NotesListActivity.this.getString( - R.string.format_exported_file_location, backup + showExportResultDialog(R.string.success_sdcard_export, + getString(R.string.format_exported_file_location, backup .getExportedTextFileName(), backup.getExportedTextFileDir())); - builder.setPositiveButton(android.R.string.ok, null); - builder.show(); } else if (result == BackupUtils.STATE_SYSTEM_ERROR) { - AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); - builder.setTitle(NotesListActivity.this - .getString(R.string.failed_sdcard_export)); - builder.setMessage(NotesListActivity.this - .getString(R.string.error_sdcard_export)); - builder.setPositiveButton(android.R.string.ok, null); - builder.show(); + showExportResultDialog(R.string.failed_sdcard_export, R.string.error_sdcard_export); } } + /** + * 显示导出结果提示对话框的辅助方法 + */ + private void showExportResultDialog(int titleResId, int messageResId) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(titleResId); + builder.setMessage(messageResId); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } }.execute(); } + /** + * 判断是否处于同步模式(已配置同步账户) + */ private boolean isSyncMode() { return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } + /** + * 启动设置活动(偏好设置) + */ private void startPreferenceActivity() { Activity from = getParent() != null ? getParent() : this; Intent intent = new Intent(from, NotesPreferenceActivity.class); - from.startActivityIfNeeded(intent, -1); + from.startActivityIfNeeded(intent, -1); // 启动活动(如需) } + /** + * 列表项点击事件监听器(处理普通点击事件) + */ private class OnListItemClickListener implements OnItemClickListener { public void onItemClick(AdapterView parent, View view, int position, long id) { if (view instanceof NotesListItem) { - NoteItemData item = ((NotesListItem) view).getItemData(); + NoteItemData item = ((NotesListItem) view).getItemData(); // 获取点击的列表项数据 + if (mNotesListAdapter.isInChoiceMode()) { + // 多选模式下处理选中状态切换(仅针对笔记项) if (item.getType() == Notes.TYPE_NOTE) { - position = position - mNotesListView.getHeaderViewsCount(); + position = position - mNotesListView.getHeaderViewsCount(); // 计算适配器中的真实位置 mModeCallBack.onItemCheckedStateChanged(null, position, id, - !mNotesListAdapter.isSelectedItem(position)); + !mNotesListAdapter.isSelectedItem(position)); // 更新选中状态 } return; } + // 根据当前状态处理不同类型的列表项点击 switch (mState) { - case NOTE_LIST: - if (item.getType() == Notes.TYPE_FOLDER - || item.getType() == Notes.TYPE_SYSTEM) { - openFolder(item); + case NOTE_LIST: // 根目录状态 + if (item.getType() == Notes.TYPE_FOLDER || item.getType() == Notes.TYPE_SYSTEM) { + openFolder(item); // 打开文件夹 } else if (item.getType() == Notes.TYPE_NOTE) { - openNode(item); + openNode(item); // 打开笔记 } else { Log.e(TAG, "Wrong note type in NOTE_LIST"); } break; - case SUB_FOLDER: - case CALL_RECORD_FOLDER: + case SUB_FOLDER: // 子文件夹状态 + case CALL_RECORD_FOLDER: // 通话记录文件夹状态 if (item.getType() == Notes.TYPE_NOTE) { - openNode(item); + openNode(item); // 打开笔记 } else { Log.e(TAG, "Wrong note type in SUB_FOLDER"); } @@ -917,11 +1006,16 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } + /** + * 启动目标文件夹查询(用于移动笔记时选择目标文件夹) + */ private void startQueryDestinationFolders() { + // 构建查询条件:类型为文件夹,非回收站,非当前文件夹(根据当前状态可能包含根目录) String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?"; - selection = (mState == ListEditState.NOTE_LIST) ? selection: - "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")"; + selection = (mState == ListEditState.NOTE_LIST) ? selection : + "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")"; + // 执行异步查询获取目标文件夹列表 mBackgroundQueryHandler.startQuery(FOLDER_LIST_QUERY_TOKEN, null, Notes.CONTENT_NOTE_URI, @@ -932,23 +1026,29 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt String.valueOf(Notes.ID_TRASH_FOLER), String.valueOf(mCurrentFolderId) }, - NoteColumns.MODIFIED_DATE + " DESC"); + NoteColumns.MODIFIED_DATE + " DESC"); // 按修改时间降序排序 } + /** + * 列表项长按事件处理(启动多选模式或显示上下文菜单) + */ public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { if (view instanceof NotesListItem) { - mFocusNoteDataItem = ((NotesListItem) view).getItemData(); + mFocusNoteDataItem = ((NotesListItem) view).getItemData(); // 获取长按的列表项数据 + if (mFocusNoteDataItem.getType() == Notes.TYPE_NOTE && !mNotesListAdapter.isInChoiceMode()) { + // 长按笔记项且非多选模式时启动多选操作栏 if (mNotesListView.startActionMode(mModeCallBack) != null) { - mModeCallBack.onItemCheckedStateChanged(null, position, id, true); - mNotesListView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + mModeCallBack.onItemCheckedStateChanged(null, position, id, true); // 标记为选中 + mNotesListView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); // 触发长按震动反馈 } else { Log.e(TAG, "startActionMode fails"); } } else if (mFocusNoteDataItem.getType() == Notes.TYPE_FOLDER) { + // 长按文件夹时显示上下文菜单 mNotesListView.setOnCreateContextMenuListener(mFolderOnCreateContextMenuListener); } } return false; } -} +} \ No newline at end of file