From 2d18da5c3d0f35c0cb5694d2fefbf810bb7f6b63 Mon Sep 17 00:00:00 2001 From: weichunyi <2948523237@qq.com> Date: Mon, 26 May 2025 13:47:00 +0800 Subject: [PATCH] =?UTF-8?q?ui-=E7=AC=94=E8=AE=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B4=BB=E5=8A=A8=E7=B1=BB=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/micode/notes/ui/NoteEditActivity.java | 490 +++++++++++------- 1 file changed, 309 insertions(+), 181 deletions(-) diff --git a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java index 96a9ff8..b1a61e5 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.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; @@ -72,18 +70,26 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * 笔记编辑活动类 + * 负责处理笔记的编辑、显示、提醒设置、界面样式调整等功能 + * 实现了点击事件监听、笔记设置变更监听、文本变更监听等接口 + */ public class NoteEditActivity extends Activity implements OnClickListener, NoteSettingChangedListener, OnTextViewChangeListener { + + /** + * 头部视图ViewHolder类 + * 用于持有笔记头部视图中的各个控件引用 + */ private class HeadViewHolder { - public TextView tvModified; - - public ImageView ivAlertIcon; - - public TextView tvAlertDate; - - public ImageView ibSetBgColor; + public TextView tvModified; // 修改时间文本视图 + public ImageView ivAlertIcon; // 提醒图标 + public TextView tvAlertDate; // 提醒时间文本视图 + public ImageView ibSetBgColor; // 设置背景颜色按钮 } + // 背景颜色选择按钮映射:按钮ID -> 背景颜色资源ID private static final Map sBgSelectorBtnsMap = new HashMap(); static { sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); @@ -93,6 +99,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); } + // 背景颜色选择选中状态映射:背景颜色资源ID -> 选中状态图标ID private static final Map sBgSelectorSelectionMap = new HashMap(); static { sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); @@ -102,6 +109,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); } + // 字体大小按钮映射:按钮ID -> 字体大小资源ID private static final Map sFontSizeBtnsMap = new HashMap(); static { sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); @@ -110,6 +118,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); } + // 字体大小选择选中状态映射:字体大小资源ID -> 选中状态图标ID private static final Map sFontSelectorSelectionMap = new HashMap(); static { sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); @@ -120,50 +129,39 @@ public class NoteEditActivity extends Activity implements OnClickListener, private static final String TAG = "NoteEditActivity"; - private HeadViewHolder mNoteHeaderHolder; - - private View mHeadViewPanel; - - private View mNoteBgColorSelector; - - private View mFontSizeSelector; - - private EditText mNoteEditor; - - private View mNoteEditorPanel; - - private WorkingNote mWorkingNote; - - private SharedPreferences mSharedPrefs; - private int mFontSizeId; - - private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; - - private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; - - public static final String TAG_CHECKED = String.valueOf('\u221A'); - public static final String TAG_UNCHECKED = String.valueOf('\u25A1'); - - private LinearLayout mEditTextList; - - private String mUserQuery; - private Pattern mPattern; + private HeadViewHolder mNoteHeaderHolder; // 头部视图ViewHolder实例 + private View mHeadViewPanel; // 头部视图面板 + private View mNoteBgColorSelector; // 背景颜色选择视图 + private View mFontSizeSelector; // 字体大小选择视图 + private EditText mNoteEditor; // 笔记编辑文本框 + private View mNoteEditorPanel; // 编辑区域面板 + private WorkingNote mWorkingNote; // 当前编辑的笔记模型 + private SharedPreferences mSharedPrefs; // 共享偏好设置 + private int mFontSizeId; // 当前字体大小ID + private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; // 字体大小偏好键 + private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; // 快捷方式标题最大长度 + public static final String TAG_CHECKED = String.valueOf('\u221A'); // 勾选标记 + public static final String TAG_UNCHECKED = String.valueOf('\u25A1'); // 未勾选标记 + private LinearLayout mEditTextList; // 列表模式下的编辑项容器 + private String mUserQuery; // 用户搜索查询词(用于高亮显示) + private Pattern mPattern; // 搜索匹配模式 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.note_edit); + // 初始化活动状态(加载已有笔记或创建新笔记) if (savedInstanceState == null && !initActivityState(getIntent())) { finish(); return; } - initResources(); + initResources(); // 初始化界面资源 } /** - * Current activity may be killed when the memory is low. Once it is killed, for another time - * user load this activity, we should restore the former state + * 恢复活动状态(处理内存不足导致的活动销毁) + * @param savedInstanceState 保存的实例状态 */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { @@ -179,24 +177,25 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } + /** + * 初始化活动状态(加载笔记或创建新笔记) + * @param intent 传入的Intent + * @return 是否初始化成功 + */ private boolean initActivityState(Intent intent) { - /** - * If the user specified the {@link Intent#ACTION_VIEW} but not provided with id, - * then jump to the NotesListActivity - */ mWorkingNote = null; + // 处理查看笔记操作 if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); mUserQuery = ""; - /** - * Starting from the searched result - */ + // 处理搜索结果中的笔记 if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) { noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); } + // 检查笔记是否存在且可见 if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) { Intent jump = new Intent(this, NotesListActivity.class); startActivity(jump); @@ -211,11 +210,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, return false; } } + // 设置软键盘模式(隐藏并调整布局) getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { - // New note + } + // 处理插入或编辑新笔记操作 + else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); @@ -224,7 +225,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, ResourceParser.getDefaultBgId(this)); - // Parse call-record note + // 处理通话记录笔记 String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); if (callDate != 0 && phoneNumber != null) { @@ -232,6 +233,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, Log.w(TAG, "The call record number is null"); } long noteId = 0; + // 检查是否已存在该通话记录笔记 if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(), phoneNumber, callDate)) > 0) { mWorkingNote = WorkingNote.load(this, noteId); @@ -241,15 +243,17 @@ public class NoteEditActivity extends Activity implements OnClickListener, return false; } } else { + // 创建新的通话记录笔记 mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); mWorkingNote.convertToCallNote(phoneNumber, callDate); } } else { + // 创建普通新笔记 mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); } - + // 设置软键盘模式(可见并调整布局) getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); @@ -258,6 +262,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, finish(); return false; } + // 设置笔记设置变更监听器 mWorkingNote.setOnSettingStatusChangedListener(this); return true; } @@ -265,48 +270,59 @@ public class NoteEditActivity extends Activity implements OnClickListener, @Override protected void onResume() { super.onResume(); - initNoteScreen(); + initNoteScreen(); // 初始化笔记界面显示 } + /** + * 初始化笔记界面显示 + */ private void initNoteScreen() { + // 设置编辑框文本样式(根据字体大小) mNoteEditor.setTextAppearance(this, TextAppearanceResources .getTexAppearanceResource(mFontSizeId)); + // 检查是否为列表模式(勾选列表) if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { - switchToListMode(mWorkingNote.getContent()); + switchToListMode(mWorkingNote.getContent()); // 切换到列表编辑模式 } else { + // 普通文本模式,显示带高亮的文本 mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); - mNoteEditor.setSelection(mNoteEditor.getText().length()); + mNoteEditor.setSelection(mNoteEditor.getText().length()); // 定位到文本末尾 } + // 隐藏所有背景颜色选择的选中状态图标 for (Integer id : sBgSelectorSelectionMap.keySet()) { findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE); } + // 设置头部视图和编辑区域背景 mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); + // 显示修改时间 mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this, mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)); - /** - * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker - * is not ready - */ + // 显示提醒时间(TODO: 后续完善提醒功能) showAlertHeader(); } + /** + * 显示提醒头部信息(提醒时间和图标) + */ private void showAlertHeader() { if (mWorkingNote.hasClockAlert()) { long time = System.currentTimeMillis(); if (time > mWorkingNote.getAlertDate()) { - mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); + mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); // 提醒已过期 } else { + // 显示相对时间(如“5分钟后”) mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS)); } mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); } else { + // 隐藏提醒相关元素 mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); }; @@ -315,26 +331,23 @@ public class NoteEditActivity extends Activity implements OnClickListener, @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - initActivityState(intent); + initActivityState(intent); // 处理新的Intent(如从搜索结果打开) } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - /** - * For new note without note id, we should firstly save it to - * generate a id. If the editing note is not worth saving, there - * is no id which is equivalent to create new note - */ + // 保存未存入数据库的新笔记(生成ID) if (!mWorkingNote.existInDatabase()) { saveNote(); } - outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); // 保存笔记ID Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { + // 点击外部区域时隐藏背景颜色和字体大小选择视图 if (mNoteBgColorSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mNoteBgColorSelector, ev)) { mNoteBgColorSelector.setVisibility(View.GONE); @@ -349,20 +362,30 @@ public class NoteEditActivity extends Activity implements OnClickListener, return super.dispatchTouchEvent(ev); } + /** + * 检查触摸事件是否在指定视图范围内 + * @param view 目标视图 + * @param ev 触摸事件 + * @return 是否在范围内 + */ private boolean inRangeOfView(View view, MotionEvent ev) { int []location = new int[2]; view.getLocationOnScreen(location); int x = location[0]; int y = location[1]; + // 判断触摸点是否在视图区域内 if (ev.getX() < x || ev.getX() > (x + view.getWidth()) || ev.getY() < y || ev.getY() > (y + view.getHeight())) { - return false; - } + return false; + } return true; } + /** + * 初始化界面资源(控件引用、事件监听等) + */ private void initResources() { mHeadViewPanel = findViewById(R.id.note_title); mNoteHeaderHolder = new HeadViewHolder(); @@ -370,44 +393,47 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon); mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date); mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color); - mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this); + mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this); // 设置背景颜色按钮点击监听 mNoteEditor = (EditText) findViewById(R.id.note_edit_view); mNoteEditorPanel = findViewById(R.id.sv_note_edit); mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector); + // 为背景颜色选择按钮设置点击监听 for (int id : sBgSelectorBtnsMap.keySet()) { ImageView iv = (ImageView) findViewById(id); iv.setOnClickListener(this); } mFontSizeSelector = findViewById(R.id.font_size_selector); + // 为字体大小选择按钮设置点击监听 for (int id : sFontSizeBtnsMap.keySet()) { View view = findViewById(id); view.setOnClickListener(this); }; mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + // 从偏好设置中获取字体大小ID,默认使用默认值 mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); - /** - * HACKME: Fix bug of store the resource id in shared preference. - * The id may larger than the length of resources, in this case, - * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE} - */ + // 处理可能的无效字体大小ID(防止越界) if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; } - mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); + mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); // 列表模式编辑容器 } @Override protected void onPause() { super.onPause(); - if(saveNote()) { + if(saveNote()) { // 保存笔记内容 Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); } - clearSettingState(); + clearSettingState(); // 清除设置状态(隐藏选择视图) } + /** + * 更新桌面小部件(当笔记关联小部件时) + */ private void updateWidget() { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + // 根据小部件类型设置对应的提供者类 if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) { intent.setClass(this, NoteWidgetProvider_2x.class); } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) { @@ -421,47 +447,68 @@ public class NoteEditActivity extends Activity implements OnClickListener, mWorkingNote.getWidgetId() }); - sendBroadcast(intent); - setResult(RESULT_OK, intent); + sendBroadcast(intent); // 发送更新广播 + setResult(RESULT_OK, intent); // 设置结果码 } + /** + * 点击事件处理 + * @param v 被点击的视图 + */ public void onClick(View v) { int id = v.getId(); + // 处理设置背景颜色按钮点击 if (id == R.id.btn_set_bg_color) { - mNoteBgColorSelector.setVisibility(View.VISIBLE); + mNoteBgColorSelector.setVisibility(View.VISIBLE); // 显示背景颜色选择视图 + // 显示当前选中的背景颜色对应的选中状态图标 findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( - - View.VISIBLE); - } else if (sBgSelectorBtnsMap.containsKey(id)) { + View.VISIBLE); + } + // 处理背景颜色选择按钮点击 + else if (sBgSelectorBtnsMap.containsKey(id)) { + // 隐藏之前选中的背景颜色的选中状态图标 findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.GONE); + // 设置新的背景颜色ID mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id)); - mNoteBgColorSelector.setVisibility(View.GONE); - } else if (sFontSizeBtnsMap.containsKey(id)) { + mNoteBgColorSelector.setVisibility(View.GONE); // 隐藏选择视图 + } + // 处理字体大小选择按钮点击 + else if (sFontSizeBtnsMap.containsKey(id)) { + // 隐藏之前选中的字体大小的选中状态图标 findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE); - mFontSizeId = sFontSizeBtnsMap.get(id); + mFontSizeId = sFontSizeBtnsMap.get(id); // 设置新的字体大小ID + // 保存字体大小到偏好设置 mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit(); + // 显示新选中的字体大小的选中状态图标 findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); + // 如果是列表模式,重新应用字体大小到所有列表项 if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { getWorkingText(); switchToListMode(mWorkingNote.getContent()); } else { + // 普通模式下直接设置编辑框文本样式 mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); } - mFontSizeSelector.setVisibility(View.GONE); + mFontSizeSelector.setVisibility(View.GONE); // 隐藏选择视图 } } @Override public void onBackPressed() { - if(clearSettingState()) { + if(clearSettingState()) { // 先清除设置状态(如有打开的选择视图) return; } - saveNote(); - super.onBackPressed(); + saveNote(); // 保存笔记 + super.onBackPressed(); // 调用父类返回逻辑 } + /** + * 清除设置状态(隐藏选择视图) + * @return 是否成功清除 + */ private boolean clearSettingState() { if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { mNoteBgColorSelector.setVisibility(View.GONE); @@ -473,9 +520,14 @@ public class NoteEditActivity extends Activity implements OnClickListener, return false; } + /** + * 背景颜色变更回调(来自笔记模型) + */ public void onBackgroundColorChanged() { + // 显示当前背景颜色的选中状态图标 findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.VISIBLE); + // 更新编辑区域和头部视图背景 mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); } @@ -485,18 +537,21 @@ public class NoteEditActivity extends Activity implements OnClickListener, if (isFinishing()) { return true; } - clearSettingState(); - menu.clear(); + clearSettingState(); // 清除设置状态 + menu.clear(); // 清空菜单 + // 根据笔记所在文件夹类型加载不同菜单(通话记录笔记专用菜单) if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) { getMenuInflater().inflate(R.menu.call_note_edit, menu); } else { getMenuInflater().inflate(R.menu.note_edit, menu); } + // 根据当前模式更新列表模式菜单项标题 if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_normal_mode); } else { menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode); } + // 根据是否有提醒设置显示/隐藏相关菜单项 if (mWorkingNote.hasClockAlert()) { menu.findItem(R.id.menu_alert).setVisible(false); } else { @@ -509,9 +564,10 @@ public class NoteEditActivity extends Activity implements OnClickListener, public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_new_note: - createNewNote(); + createNewNote(); // 创建新笔记 break; case R.id.menu_delete: + // 显示删除确认对话框 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.alert_title_delete)); builder.setIcon(android.R.drawable.ic_dialog_alert); @@ -519,7 +575,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - deleteCurrentNote(); + deleteCurrentNote(); // 删除当前笔记 finish(); } }); @@ -527,25 +583,27 @@ public class NoteEditActivity extends Activity implements OnClickListener, builder.show(); break; case R.id.menu_font_size: - mFontSizeSelector.setVisibility(View.VISIBLE); + mFontSizeSelector.setVisibility(View.VISIBLE); // 显示字体大小选择视图 + // 显示当前选中的字体大小的选中状态图标 findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); break; case R.id.menu_list_mode: + // 切换列表模式状态 mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ? TextNote.MODE_CHECK_LIST : 0); break; case R.id.menu_share: - getWorkingText(); - sendTo(this, mWorkingNote.getContent()); + getWorkingText(); // 获取当前笔记内容 + sendTo(this, mWorkingNote.getContent()); // 分享笔记内容 break; case R.id.menu_send_to_desktop: - sendToDesktop(); + sendToDesktop(); // 发送到桌面创建快捷方式 break; case R.id.menu_alert: - setReminder(); + setReminder(); // 设置提醒时间 break; case R.id.menu_delete_remind: - mWorkingNote.setAlertDate(0, false); + mWorkingNote.setAlertDate(0, false); // 清除提醒时间 break; default: break; @@ -553,32 +611,39 @@ public class NoteEditActivity extends Activity implements OnClickListener, return true; } + /** + * 设置提醒时间(打开日期时间选择对话框) + */ private void setReminder() { DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); d.setOnDateTimeSetListener(new OnDateTimeSetListener() { public void OnDateTimeSet(AlertDialog dialog, long date) { - mWorkingNote.setAlertDate(date , true); + mWorkingNote.setAlertDate(date, true); // 设置提醒时间并启用提醒 } }); d.show(); } /** - * Share note to apps that support {@link Intent#ACTION_SEND} action - * and {@text/plain} type + * 分享笔记内容到其他应用 + * @param context 上下文 + * @param info 要分享的内容 */ private void sendTo(Context context, String info) { Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, info); - intent.setType("text/plain"); + intent.setType("text/plain"); // 设置分享类型为纯文本 context.startActivity(intent); } + /** + * 创建新笔记(保存当前笔记后启动新的编辑活动) + */ private void createNewNote() { - // Firstly, save current editing notes + // 先保存当前编辑的笔记 saveNote(); - // For safety, start a new NoteEditActivity + // 启动新的笔记编辑活动 finish(); Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_INSERT_OR_EDIT); @@ -586,6 +651,9 @@ public class NoteEditActivity extends Activity implements OnClickListener, startActivity(intent); } + /** + * 删除当前笔记 + */ private void deleteCurrentNote() { if (mWorkingNote.existInDatabase()) { HashSet ids = new HashSet(); @@ -595,6 +663,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } else { Log.d(TAG, "Wrong note id, should not happen"); } + // 根据是否为同步模式处理删除(移动到回收站或直接删除) if (!isSyncMode()) { if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { Log.e(TAG, "Delete Note error"); @@ -605,18 +674,24 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } } - mWorkingNote.markDeleted(true); + mWorkingNote.markDeleted(true); // 标记笔记为已删除 } + /** + * 判断是否为同步模式(存在同步账户) + * @return 是否为同步模式 + */ private boolean isSyncMode() { return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } + /** + * 提醒时间变更回调(来自笔记模型) + * @param date 提醒时间 + * @param set 是否设置提醒 + */ public void onClockAlertChanged(long date, boolean set) { - /** - * User could set clock to an unsaved note, so before setting the - * alert clock, we should save the note first - */ + // 未保存的笔记需要先保存才能设置提醒 if (!mWorkingNote.existInDatabase()) { saveNote(); } @@ -625,39 +700,44 @@ public class NoteEditActivity extends Activity implements OnClickListener, intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId())); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); - showAlertHeader(); + showAlertHeader(); // 更新提醒头部显示 if(!set) { - alarmManager.cancel(pendingIntent); + alarmManager.cancel(pendingIntent); // 取消提醒 } else { - alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); + alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); // 设置提醒 } } else { - /** - * There is the condition that user has input nothing (the note is - * not worthy saving), we have no note id, remind the user that he - * should input something - */ + // 处理笔记内容为空的情况 Log.e(TAG, "Clock alert setting error"); showToast(R.string.error_note_empty_for_clock); } } + /** + * 小部件变更回调(来自笔记模型) + */ public void onWidgetChanged() { - updateWidget(); + updateWidget(); // 更新桌面小部件 } + /** + * 列表模式编辑项删除回调 + * @param index 删除项索引 + * @param text 删除项文本 + */ public void onEditTextDelete(int index, String text) { int childCount = mEditTextList.getChildCount(); if (childCount == 1) { return; } + // 调整后续项的索引 for (int i = index + 1; i < childCount; i++) { ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) .setIndex(i - 1); } - mEditTextList.removeViewAt(index); + mEditTextList.removeViewAt(index); // 删除视图 NoteEditText edit = null; if(index == 0) { edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( @@ -667,54 +747,68 @@ public class NoteEditActivity extends Activity implements OnClickListener, R.id.et_edit_text); } int length = edit.length(); - edit.append(text); + edit.append(text); // 将删除项文本添加到前一项 edit.requestFocus(); - edit.setSelection(length); + edit.setSelection(length); // 定位到文本末尾 } + /** + * 列表模式编辑项换行回调(创建新项) + * @param index 新项索引 + * @param text 新项文本 + */ public void onEditTextEnter(int index, String text) { - /** - * Should not happen, check for debug - */ if(index > mEditTextList.getChildCount()) { Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); } - View view = getListItem(text, index); - mEditTextList.addView(view, index); + View view = getListItem(text, index); // 创建新的列表项视图 + mEditTextList.addView(view, index); // 添加到列表 NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); - edit.requestFocus(); - edit.setSelection(0); + edit.requestFocus(); // 获取焦点 + edit.setSelection(0); // 定位到文本开头 + // 调整后续项的索引 for (int i = index + 1; i < mEditTextList.getChildCount(); i++) { ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) .setIndex(i); } } + /** + * 切换到列表编辑模式 + * @param text 笔记内容文本 + */ private void switchToListMode(String text) { - mEditTextList.removeAllViews(); - String[] items = text.split("\n"); + mEditTextList.removeAllViews(); // 清空列表容器 + String[] items = text.split("\n"); // 按换行分割文本 int index = 0; for (String item : items) { if(!TextUtils.isEmpty(item)) { - mEditTextList.addView(getListItem(item, index)); + mEditTextList.addView(getListItem(item, index)); // 添加列表项视图 index++; } } - mEditTextList.addView(getListItem("", index)); - mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); + mEditTextList.addView(getListItem("", index)); // 添加空的新项 + mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); // 焦点定位到新项 - mNoteEditor.setVisibility(View.GONE); - mEditTextList.setVisibility(View.VISIBLE); + mNoteEditor.setVisibility(View.GONE); // 隐藏普通编辑框 + mEditTextList.setVisibility(View.VISIBLE); // 显示列表编辑容器 } + /** + * 获取带搜索词高亮的文本 + * @param fullText 完整文本 + * @param userQuery 搜索查询词 + * @return 带高亮标记的Spannable字符串 + */ private Spannable getHighlightQueryResult(String fullText, String userQuery) { SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); if (!TextUtils.isEmpty(userQuery)) { - mPattern = Pattern.compile(userQuery); + mPattern = Pattern.compile(userQuery); // 编译搜索模式 Matcher m = mPattern.matcher(fullText); int start = 0; while (m.find(start)) { + // 设置背景颜色高亮 spannable.setSpan( new BackgroundColorSpan(this.getResources().getColor( R.color.user_query_highlight)), m.start(), m.end(), @@ -725,21 +819,30 @@ public class NoteEditActivity extends Activity implements OnClickListener, return spannable; } + /** + * 创建列表模式下的单个编辑项视图 + * @param item 项文本内容 + * @param index 项索引 + * @return 列表项视图 + */ private View getListItem(String item, int index) { View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + // 设置文本样式(根据字体大小) edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item)); + // 勾选状态变更监听(处理删除线效果) cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { - edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); // 添加删除线 } else { - edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); // 清除删除线 } } }); + // 解析文本中的勾选标记 if (item.startsWith(TAG_CHECKED)) { cb.setChecked(true); edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); @@ -750,17 +853,23 @@ public class NoteEditActivity extends Activity implements OnClickListener, item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); } - edit.setOnTextViewChangeListener(this); - edit.setIndex(index); - edit.setText(getHighlightQueryResult(item, mUserQuery)); + edit.setOnTextViewChangeListener(this); // 设置文本变更监听 + edit.setIndex(index); // 设置项索引 + edit.setText(getHighlightQueryResult(item, mUserQuery)); // 显示带高亮的文本 return view; } + /** + * 列表模式文本变更回调 + * @param index 变更项索引 + * @param hasText 是否有文本内容 + */ public void onTextChange(int index, boolean hasText) { if (index >= mEditTextList.getChildCount()) { Log.e(TAG, "Wrong index, should not happen"); return; } + // 根据是否有文本显示/隐藏勾选框 if(hasText) { mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE); } else { @@ -768,24 +877,36 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } + /** + * 列表模式状态变更回调 + * @param oldMode 旧模式 + * @param newMode 新模式 + */ public void onCheckListModeChanged(int oldMode, int newMode) { if (newMode == TextNote.MODE_CHECK_LIST) { - switchToListMode(mNoteEditor.getText().toString()); + switchToListMode(mNoteEditor.getText().toString()); // 切换到列表模式 } else { if (!getWorkingText()) { + // 切换回普通模式时处理勾选标记 mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", "")); } + // 显示带高亮的普通文本 mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); - mEditTextList.setVisibility(View.GONE); - mNoteEditor.setVisibility(View.VISIBLE); + mEditTextList.setVisibility(View.GONE); // 隐藏列表编辑容器 + mNoteEditor.setVisibility(View.VISIBLE); // 显示普通编辑框 } } + /** + * 获取当前笔记内容(根据模式处理列表项或普通文本) + * @return 是否包含勾选项 + */ private boolean getWorkingText() { boolean hasChecked = false; if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { StringBuilder sb = new StringBuilder(); + // 遍历列表项生成带勾选标记的文本 for (int i = 0; i < mEditTextList.getChildCount(); i++) { View view = mEditTextList.getChildAt(i); NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); @@ -798,35 +919,31 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } } - mWorkingNote.setWorkingText(sb.toString()); + mWorkingNote.setWorkingText(sb.toString()); // 设置笔记内容 } else { - mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); + mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); // 普通模式直接获取文本 } return hasChecked; } + /** + * 保存笔记内容到数据库 + * @return 是否保存成功 + */ private boolean saveNote() { - getWorkingText(); - boolean saved = mWorkingNote.saveNote(); + getWorkingText(); // 获取当前内容 + boolean saved = mWorkingNote.saveNote(); // 保存笔记 if (saved) { - /** - * There are two modes from List view to edit view, open one note, - * create/edit a node. Opening node requires to the original - * position in the list when back from edit view, while creating a - * new node requires to the top of the list. This code - * {@link #RESULT_OK} is used to identify the create/edit state - */ - setResult(RESULT_OK); + setResult(RESULT_OK); // 设置结果码为成功 } return saved; } + /** + * 发送到桌面创建快捷方式 + */ private void sendToDesktop() { - /** - * Before send message to home, we should make sure that current - * editing note is exists in databases. So, for new note, firstly - * save it - */ + // 未保存的笔记需要先保存 if (!mWorkingNote.existInDatabase()) { saveNote(); } @@ -835,39 +952,50 @@ public class NoteEditActivity extends Activity implements OnClickListener, Intent sender = new Intent(); Intent shortcutIntent = new Intent(this, NoteEditActivity.class); shortcutIntent.setAction(Intent.ACTION_VIEW); - shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); // 设置快捷方式目标笔记ID sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + // 设置快捷方式标题(截断到最大长度) sender.putExtra(Intent.EXTRA_SHORTCUT_NAME, makeShortcutIconTitle(mWorkingNote.getContent())); sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app)); sender.putExtra("duplicate", true); - sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); - showToast(R.string.info_note_enter_desktop); - sendBroadcast(sender); + sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); // 安装快捷方式动作 + showToast(R.string.info_note_enter_desktop); // 显示提示 + sendBroadcast(sender); // 发送广播 } else { - /** - * There is the condition that user has input nothing (the note is - * not worthy saving), we have no note id, remind the user that he - * should input something - */ + // 处理内容为空的情况 Log.e(TAG, "Send to desktop error"); showToast(R.string.error_note_empty_for_send_to_desktop); } } + /** + * 生成快捷方式标题(去除勾选标记并截断长度) + * @param content 笔记内容 + * @return 处理后的标题 + */ private String makeShortcutIconTitle(String content) { - content = content.replace(TAG_CHECKED, ""); - content = content.replace(TAG_UNCHECKED, ""); + content = content.replace(TAG_CHECKED, ""); // 移除勾选标记 + content = content.replace(TAG_UNCHECKED, ""); // 移除未勾选标记 return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0, - SHORTCUT_ICON_TITLE_MAX_LEN) : content; + SHORTCUT_ICON_TITLE_MAX_LEN) : content; // 截断到最大长度 } + /** + * 显示Toast提示 + * @param resId 提示文本资源ID + */ private void showToast(int resId) { showToast(resId, Toast.LENGTH_SHORT); } + /** + * 显示Toast提示(支持自定义时长) + * @param resId 提示文本资源ID + * @param duration Toast时长 + */ private void showToast(int resId, int duration) { Toast.makeText(this, resId, duration).show(); } -} +} \ No newline at end of file