diff --git a/src/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 97a44840..ca810866 100644 --- a/src/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/src/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -71,7 +71,7 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; - +//便签编辑有关的活动,实现了 OnClickListener(处理点击事件)、NoteSettingChangedListener(监测便签设置的变动) 和 OnTextViewChangeListener(监测便签编辑的变动) 接口, public class NoteEditActivity extends Activity implements OnClickListener, NoteSettingChangedListener, OnTextViewChangeListener { private class HeadViewHolder { @@ -132,7 +132,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, private View mNoteEditorPanel; - private WorkingNote mWorkingNote; + private WorkingNote mWorkingNote; //记录当前正在工作的便签 private SharedPreferences mSharedPrefs; private int mFontSizeId; @@ -165,18 +165,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, * 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 */ - @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - // 恢复之前保存的状态 if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) { - // 构建一个带有 ACTION_VIEW 的 Intent,并传递之前保存的笔记id Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID)); - // 初始化Activity的工作状态 if (!initActivityState(intent)) { - // 如果初始化失败,则结束当前Activity finish(); return; } @@ -184,29 +179,32 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } + //依据intent参数传递的Action采取动作 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())) { - // 如果用户指定了ACTION_VIEW但没有提供id,则跳转到NotesListActivity 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)) { - // 如果数据库中不存在指定的笔记,则跳转到NotesListActivity并显示错误信息 Intent jump = new Intent(this, NotesListActivity.class); startActivity(jump); showToast(R.string.error_note_not_exist); finish(); return false; } else { - // 加载指定id的笔记 mWorkingNote = WorkingNote.load(this, noteId); if (mWorkingNote == null) { Log.e(TAG, "load note failed with note id" + noteId); @@ -218,7 +216,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, 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 long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); @@ -226,8 +224,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, Notes.TYPE_WIDGET_INVALIDE); 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) { @@ -237,7 +235,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, long noteId = 0; if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(), phoneNumber, callDate)) > 0) { - // 加载指定id的来电记录笔记 mWorkingNote = WorkingNote.load(this, noteId); if (mWorkingNote == null) { Log.e(TAG, "load call note failed with note id" + noteId); @@ -245,443 +242,309 @@ 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); } else { - // 如果Intent没有指定操作,则不应该支持该Intent,记录错误并关闭当前Activity Log.e(TAG, "Intent not specified action, should not support"); finish(); return false; } - // 设置工作状态改变监听器并返回true表示初始化成功 mWorkingNote.setOnSettingStatusChangedListener(this); return true; } -@Override -protected void onResume() { - super.onResume(); - initNoteScreen(); // 初始化笔记界面 -} - -private void initNoteScreen() { - // 设置笔记编辑器的文本外观 - mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); - - // 根据工作笔记的模式进行不同的处理 - if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { - // 如果是清单模式,将编辑器切换到清单模式 - switchToListMode(mWorkingNote.getContent()); - } else { - // 如果不是清单模式,将编辑器的文本设置为工作笔记的内容 - mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); - // 将光标设置在文本末尾 - mNoteEditor.setSelection(mNoteEditor.getText().length()); - } - - // 隐藏背景选择器中当前选中的项 - for (Integer id : sBgSelectorSelectionMap.keySet()) { - findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE); + @Override + protected void onResume() { + super.onResume(); + initNoteScreen(); } - // 设置标题栏的背景资源 - 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 - */ - showAlertHeader(); // 显示提醒信息(如果有) -} - -private void showAlertHeader() { - // 如果工作笔记设置了提醒 - if (mWorkingNote.hasClockAlert()) { - long time = System.currentTimeMillis(); - if (time > mWorkingNote.getAlertDate()) { - // 如果提醒时间已过期,显示"提醒已过期" - mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); + private void initNoteScreen() { + mNoteEditor.setTextAppearance(this, TextAppearanceResources + .getTexAppearanceResource(mFontSizeId)); + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + switchToListMode(mWorkingNote.getContent()); } else { - // 否则,显示距提醒时间的相对时间 - mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( - mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS)); + mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + mNoteEditor.setSelection(mNoteEditor.getText().length()); } - // 显示提醒时间文本和提醒图标 - mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE); - mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); - } else { - // 如果工作笔记没有设置提醒,隐藏提醒时间文本和提醒图标 - mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); - mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); - }; -} - - + for (Integer id : sBgSelectorSelectionMap.keySet()) { + findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE); + } + mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); + mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); -@Override -protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - initActivityState(intent); -} + mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this, + mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_YEAR)); -@Override -protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - /** - * 如果编辑的笔记尚未在数据库中存在(没有ID),我们先保存它以生成一个ID。 - * 如果正在编辑的笔记不值得保存,则没有ID等同于创建新的笔记。 - */ - if (!mWorkingNote.existInDatabase()) { - saveNote(); + /** + * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker + * is not ready + */ + showAlertHeader(); } - - outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); - Log.d(TAG, "保存正在编辑的笔记ID:" + mWorkingNote.getNoteId() + ",onSaveInstanceState"); -} -@Override -public boolean dispatchTouchEvent(MotionEvent ev) { - // 如果笔记背景颜色选择器可见,并且触摸事件的位置不在选择器内,隐藏选择器并返回true - if (mNoteBgColorSelector.getVisibility() == View.VISIBLE - && !inRangeOfView(mNoteBgColorSelector, ev)) { - mNoteBgColorSelector.setVisibility(View.GONE); - return true; + private void showAlertHeader() { + if (mWorkingNote.hasClockAlert()) { + long time = System.currentTimeMillis(); + if (time > mWorkingNote.getAlertDate()) { + mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); + } else { + 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); + }; } - // 如果字体大小选择器可见,并且触摸事件的位置不在选择器内,隐藏选择器并返回true - if (mFontSizeSelector.getVisibility() == View.VISIBLE - && !inRangeOfView(mFontSizeSelector, ev)) { - mFontSizeSelector.setVisibility(View.GONE); - return true; + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + initActivityState(intent); } - - // 如果触摸事件位置没有被处理,则调用父类的dispatchTouchEvent方法处理事件 - return super.dispatchTouchEvent(ev); -} -/** - * 检查触摸事件的位置是否在给定View内部 - * - * @param view 要检查的View - * @param ev 触摸事件 - * @return 触摸事件位置是否在View内部 - */ -private boolean inRangeOfView(View view, MotionEvent ev) { - int[] location = new int[2]; - view.getLocationOnScreen(location); - int x = location[0]; - int y = location[1]; - - // 如果触摸事件的位置超出了View的边界,则返回false - if (ev.getX() < x - || ev.getX() > (x + view.getWidth()) - || ev.getY() < y - || ev.getY() > (y + view.getHeight())) { - return false; + @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 + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); } - - return true; -} -private void initResources() { - // 初始化控件和资源 - - // 获取布局中的note_title并赋值给mHeadViewPanel - mHeadViewPanel = findViewById(R.id.note_title); - - // 创建HeadViewHolder实例 - mNoteHeaderHolder = new HeadViewHolder(); - // 获取布局中的tv_modified_date并赋值给mNoteHeaderHolder中的tvModified - mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date); - // 获取布局中的iv_alert_icon并赋值给mNoteHeaderHolder中的ivAlertIcon - mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon); - // 获取布局中的tv_alert_date并赋值给mNoteHeaderHolder中的tvAlertDate - mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date); - // 获取布局中的btn_set_bg_color并赋值给mNoteHeaderHolder中的ibSetBgColor - mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color); - // 设置ibSetBgColor的点击事件监听器为当前Activity(this) - mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this); - - // 获取布局中的note_edit_view并赋值给mNoteEditor - mNoteEditor = (EditText) findViewById(R.id.note_edit_view); - // 获取布局中的sv_note_edit并赋值给mNoteEditorPanel - mNoteEditorPanel = findViewById(R.id.sv_note_edit); - - // 获取布局中的note_bg_color_selector并赋值给mNoteBgColorSelector - mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector); - // 遍历sBgSelectorBtnsMap中的按钮ID,并为每个按钮设置点击事件监听器为当前Activity(this) - for (int id : sBgSelectorBtnsMap.keySet()) { - ImageView iv = (ImageView) findViewById(id); - iv.setOnClickListener(this); - } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (mNoteBgColorSelector.getVisibility() == View.VISIBLE + && !inRangeOfView(mNoteBgColorSelector, ev)) { + mNoteBgColorSelector.setVisibility(View.GONE); + return true; + } - // 获取布局中的font_size_selector并赋值给mFontSizeSelector - mFontSizeSelector = findViewById(R.id.font_size_selector); - // 遍历sFontSizeBtnsMap中的按钮ID,并为每个按钮设置点击事件监听器为当前Activity(this) - for (int id : sFontSizeBtnsMap.keySet()) { - View view = findViewById(id); - view.setOnClickListener(this); - }; - - // 获取默认的SharedPreferences实例 - mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - // 从SharedPreferences中获取设置的字体大小ID,默认值为ResourceParser.BG_DEFAULT_FONT_SIZE - mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); - /** - * HACKME: 修复存储资源ID的共享偏好的bug。 - * ID可能大于资源的长度,在这种情况下, - * 将其设置为ResourceParser.BG_DEFAULT_FONT_SIZE。 - */ - if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { - mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; + if (mFontSizeSelector.getVisibility() == View.VISIBLE + && !inRangeOfView(mFontSizeSelector, ev)) { + mFontSizeSelector.setVisibility(View.GONE); + return true; + } + return super.dispatchTouchEvent(ev); + } + + 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 true; } - // 获取布局中的note_edit_list并赋值给mEditTextList - mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); -} + private void initResources() { + mHeadViewPanel = findViewById(R.id.note_title); + mNoteHeaderHolder = new HeadViewHolder(); + mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date); + 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); + 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); + } -@Override -protected void onPause() { - super.onPause(); - // 当Activity暂停时,保存笔记数据并输出日志 - if(saveNote()) { - Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); + mFontSizeSelector = findViewById(R.id.font_size_selector); + for (int id : sFontSizeBtnsMap.keySet()) { + View view = findViewById(id); + view.setOnClickListener(this); + }; + mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + 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} + */ + if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { + mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; + } + mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); } - // 清除设置状态 - 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) { - intent.setClass(this, NoteWidgetProvider_4x.class); - } else { - // 不支持的小部件类型,输出错误日志并返回 - Log.e(TAG, "Unspported widget type"); - return; + @Override + protected void onPause() { + super.onPause(); + if(saveNote()) { + Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); + } + clearSettingState(); } - // 将工作笔记的小部件ID作为额外数据放入意图中 - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { - mWorkingNote.getWidgetId() - }); + 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) { + intent.setClass(this, NoteWidgetProvider_4x.class); + } else { + Log.e(TAG, "Unspported widget type"); + return; + } - // 发送广播来更新小部件 - sendBroadcast(intent); - setResult(RESULT_OK, intent); -} + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { + mWorkingNote.getWidgetId() + }); -public void onClick(View v) { - // 获取当前点击的控件的ID - int id = v.getId(); - if (id == R.id.btn_set_bg_color) { - // 如果点击的是设置背景颜色的按钮 - // 显示背景颜色选择器 - mNoteBgColorSelector.setVisibility(View.VISIBLE); - // 显示当前工作笔记背景颜色的选择项 - findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(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)) { - // 如果点击的是字体大小选择器中的一个按钮 - // 隐藏当前字体大小的选择项 - findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE); - // 设置新的字体大小ID - mFontSizeId = sFontSizeBtnsMap.get(id); - // 将新的字体大小ID保存到SharedPreferences中 - 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)); + sendBroadcast(intent); + setResult(RESULT_OK, intent); + } + + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.btn_set_bg_color) { + mNoteBgColorSelector.setVisibility(View.VISIBLE); + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + - View.VISIBLE); + } else if (sBgSelectorBtnsMap.containsKey(id)) { + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + View.GONE); + mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id)); + mNoteBgColorSelector.setVisibility(View.GONE); + } else if (sFontSizeBtnsMap.containsKey(id)) { + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE); + mFontSizeId = sFontSizeBtnsMap.get(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()) { - // 如果当前状态是设置状态,清除设置状态并返回 - return; - } + @Override + public void onBackPressed() { + if(clearSettingState()) { + return; + } - // 保存工作笔记 - saveNote(); - super.onBackPressed(); -} + saveNote(); + super.onBackPressed(); + } -private boolean clearSettingState() { - // 清除设置状态方法 - if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { - // 如果背景颜色选择器可见 - // 隐藏背景颜色选择器 - mNoteBgColorSelector.setVisibility(View.GONE); - return true; - } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) { - // 如果字体大小选择器可见 - // 隐藏字体大小选择器 - mFontSizeSelector.setVisibility(View.GONE); - return true; + private boolean clearSettingState() { + if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { + mNoteBgColorSelector.setVisibility(View.GONE); + return true; + } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) { + mFontSizeSelector.setVisibility(View.GONE); + return true; + } + return false; } - return false; -} -public void onBackgroundColorChanged() { - // 根据当前工作笔记的背景颜色ID显示相应的选择项 - findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(View.VISIBLE); - // 设置工作笔记编辑面板的背景颜色为当前工作笔记的背景颜色资源ID - mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); - // 设置工作笔记标题栏的背景颜色为当前工作笔记的标题背景资源ID - mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); -} + public void onBackgroundColorChanged() { + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + View.VISIBLE); + mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); + mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); + } -@Override -public boolean onPrepareOptionsMenu(Menu menu) { - // 菜单准备方法,动态显示菜单项 - if (isFinishing()) { + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (isFinishing()) { + return true; + } + 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 { + menu.findItem(R.id.menu_delete_remind).setVisible(false); + } return true; } - // 清除设置状态 - 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 { - // 隐藏菜单项“删除提醒” - menu.findItem(R.id.menu_delete_remind).setVisible(false); - } - return true; -} - -@Override -public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == R.id.menu_new_note) { - // 当点击菜单项“新建笔记”时 - createNewNote(); - } else if (itemId == 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); - builder.setMessage(getString(R.string.alert_message_delete_note)); - builder.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // 确认删除工作笔记,删除并结束当前活动 - deleteCurrentNote(); - finish(); - } - }); - builder.setNegativeButton(android.R.string.cancel, null); - builder.show(); - } else if (itemId == R.id.menu_font_size) { - // 当点击菜单项“字体大小”时 - // 显示字体大小选择器,并根据当前字体大小ID显示相应的选择项 - mFontSizeSelector.setVisibility(View.VISIBLE); - findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); - } else if (itemId == R.id.menu_list_mode) { - // 当点击菜单项“模式切换”时 - // 切换工作笔记的待办事项模式 - mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ? - TextNote.MODE_CHECK_LIST : 0); - } else if (itemId == R.id.menu_share) { - // 当点击菜单项“分享”时 - // 获取当前工作文本并进行分享 - getWorkingText(); - sendTo(this, mWorkingNote.getContent()); - } else if (itemId == R.id.menu_send_to_desktop) { - // 当点击菜单项“发送到桌面”时 - sendToDesktop(); - } else if (itemId == R.id.menu_alert) { - // 当点击菜单项“提醒”时 - // 设置闹钟提醒 - setReminder(); - } else if (itemId == R.id.menu_delete_remind) { - // 当点击菜单项“删除提醒”时 - // 清除工作笔记的提醒日期和提醒标志 - mWorkingNote.setAlertDate(0, false); + //实现便签的各种功能 + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int itemId = item.getItemId(); + if (itemId == R.id.menu_new_note) { + createNewNote(); //新建便签 + } else if (itemId == R.id.menu_delete) { //删除便签 + AlertDialog.Builder builder = new AlertDialog.Builder(this); //创建一个 AlertDialog.Builder 对象,用于构建对话框 + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_note)); + builder.setPositiveButton(android.R.string.ok, //点击ok则删除该便签 + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + deleteCurrentNote(); + finish(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } else if (itemId == R.id.menu_font_size) { //设置字体大小 + mFontSizeSelector.setVisibility(View.VISIBLE); + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); + } else if (itemId == R.id.menu_list_mode) { + mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ? + TextNote.MODE_CHECK_LIST : 0); + } else if (itemId == R.id.menu_share) { //分享 + getWorkingText(); + sendTo(this, mWorkingNote.getContent()); + } else if (itemId == R.id.menu_send_to_desktop) { //发送到桌面 + sendToDesktop(); + } else if (itemId == R.id.menu_alert) { //设置提醒 + setReminder(); + } else if (itemId == R.id.menu_delete_remind) { + mWorkingNote.setAlertDate(0, false); + } + return true; } - return true; -} private void setReminder() { -/* - * 这段 Java 代码实现了一个名为 `setReminder()` 的方法,用于设置笔记的提醒功能。以下是对该方法的解释: -1. 首先,创建一个 `DateTimePickerDialog` 对象 `d`,用于显示日期时间选择对话框。 -2. 通过传递 System.currentTimeMillis() 方法的返回值,设置初始日期时间选择为当前时间。 -3. 将一个匿名的 `OnDateTimeSetListener` 实例设置给 `d`,用于在用户选择日期时间后响应事件。 -4. 在 `OnDateTimeSet` 方法中,获取用户选择的日期时间, -并通过调用 `mWorkingNote` 对象的 `setAlertDate()` 方法设置笔记的提醒日期时间。 -5. 最后,通过调用 `d` 对象的 `show()` 方法,显示日期时间选择对话框。 -综上,该方法实现了通过日期时间选择对话框设置笔记提醒功能的功能,用户能够通过该对话框选择想要提醒的日期时间点。 -在用户选择日期时间后,将所选日期时间点保存到 `mWorkingNote` 对象中,以实现笔记的提醒功能。 - */ DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); d.setOnDateTimeSetListener(new OnDateTimeSetListener() { public void OnDateTimeSet(AlertDialog dialog, long date) { @@ -696,23 +559,13 @@ public boolean onOptionsItemSelected(MenuItem item) { * and {@text/plain} type */ private void sendTo(Context context, String info) { - /* -这是一个名为 `sendTo()` 的私有方法,用于发送信息。 -该方法接受两个参数,一个是上下文(`context`),一个是要发送的信息(`info`)。 -方法的具体步骤如下: -1. 创建一个 `Intent` 对象,使用 `Intent.ACTION_SEND` 动作。这表示我们要发送数据。 -2. 使用 `intent.putExtra()` 方法将要发送的文本数据添加到 `Intent` 中。 -键为 `Intent.EXTRA_TEXT`,值为 `info`,即要发送的信息内容。 -3. 使用 `intent.setType()` 方法指定发送的数据类型为纯文本("text/plain")。 -4. 调用 `context.startActivity(intent)` 启动该意图,从而触发系统选择合适的应用程序来处理发送操作。 - */ - Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, info); intent.setType("text/plain"); context.startActivity(intent); } + //创建新的便签函数 private void createNewNote() { // Firstly, save current editing notes saveNote(); @@ -722,18 +575,9 @@ public boolean onOptionsItemSelected(MenuItem item) { Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_INSERT_OR_EDIT); intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId()); - startActivity(intent);/* - 这段代码是一个方法 `createNewNote()` 的实现。下面是对代码的解释: -1. 首先,调用 `saveNote()` 方法保存当前正在编辑的笔记。 -2. 为了安全起见,在开始新的笔记之前,调用 `finish()` 方法关闭当前的 Activity。 -3. 创建一个新的 `Intent` 对象,将目标 Activity 设置为 `NoteEditActivity`(笔记编辑界面)。 -4. 使用 `Intent.ACTION_INSERT_OR_EDIT` 设置操作,表示是插入或编辑操作。 -5. 使用 `intent.putExtra()` 将当前笔记所属的文件夹的 ID 作为附加数据传递给 `NoteEditActivity`。 -6. 最后,调用 `startActivity(intent)` 启动 `NoteEditActivity`。 -这将打开一个新的笔记编辑界面,并根据传递的附加数据进行相应的操作。 - */ + startActivity(intent); } - + //删除当前工作的便签 private void deleteCurrentNote() { if (mWorkingNote.existInDatabase()) { HashSet ids = new HashSet(); @@ -753,259 +597,184 @@ public boolean onOptionsItemSelected(MenuItem item) { } } } - mWorkingNote.markDeleted(true); -/* - * 这段代码是一个方法 `deleteCurrentNote()` 的实现。下面是对代码的解释: -1. 首先,检查 `mWorkingNote` 是否存在于数据库中,即当前的笔记是否已经保存在数据库中。 -2. 如果存在于数据库中,创建一个 `HashSet` 集合 `ids`,用于存储需要删除的笔记的 ID。 -3. 获取当前笔记的 ID,并将其添加到 `ids` 集合中。 -4. 检查当前笔记的 ID 是否等于 `Notes.ID_ROOT_FOLDER`,如果不是,将其添加到 `ids` 集合中。 -5. 如果不是处于同步模式下(`isSyncMode()` 返回 `false`), -则调用 `DataUtils.batchDeleteNotes()` 方法批量删除数据库中的笔记。如果删除失败,打印错误日志信息。 -6. 如果处于同步模式下,调用 `DataUtils.batchMoveToFolder()` 方法 -将笔记批量移动到垃圾箱。如果移动失败,打印错误日志信息。 -7. 调用 `mWorkingNote.markDeleted(true)` 方法,将当前笔记标记为已删除。 -这段代码的作用是将当前的笔记标记为已删除,并根据不同的条件执行相应的操作: -如果不是同步模式,则删除数据库中的笔记;如果是同步模式,则将笔记移动到垃圾箱。 - */ + mWorkingNote.markDeleted(true); //标记删除 } -// 判断是否为同步模式 -private boolean isSyncMode() { - return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; -} - -// 当闹钟提醒设置改变时的处理 -public void onClockAlertChanged(long date, boolean set) { - // 如果当前工作笔记不存在于数据库中,则保存笔记 - if (!mWorkingNote.existInDatabase()) { - saveNote(); + private boolean isSyncMode() { + return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } - // 如果工作笔记的ID大于0,则继续处理 - if (mWorkingNote.getNoteId() > 0) { - // 创建AlarmReceiver的Intent - Intent intent = new Intent(this, AlarmReceiver.class); - intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId())); - // 创建用于广播的PendingIntent - PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); - // 获取AlarmManager实例 - AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); - // 显示提醒标题 - showAlertHeader(); - // 根据set参数判断是否设置或取消闹钟提醒 - if(!set) { - alarmManager.cancel(pendingIntent); // 取消闹钟提醒 + + 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(); + } + if (mWorkingNote.getNoteId() > 0) { + Intent intent = new Intent(this, AlarmReceiver.class); + 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(); + if(!set) { + alarmManager.cancel(pendingIntent); + } else { + alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); + } } else { - alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); // 设置闹钟提醒 + /** + * 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); } - } else { - // 如果工作笔记ID小于等于0,记录错误并显示提示 - Log.e(TAG, "Clock alert setting error"); - showToast(R.string.error_note_empty_for_clock); - } -} - -// 当小部件改变时的处理 -public void onWidgetChanged() { - updateWidget(); // 更新小部件 -} - -// 当文本编辑框内容删除时的处理 -public void onEditTextDelete(int index, String text) { - int childCount = mEditTextList.getChildCount(); - // 如果子View数量为1,则直接返回 - 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); + public void onWidgetChanged() { + updateWidget(); } - // 移除指定位置的编辑框 - mEditTextList.removeViewAt(index); - NoteEditText edit = null; - // 获取上一个编辑框,如果是第一个则获取第一个编辑框 - if(index == 0) { - edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById(R.id.et_edit_text); - } else { - edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById(R.id.et_edit_text); - } - int length = edit.length(); - // 在编辑框末尾添加指定文本 - edit.append(text); - edit.requestFocus(); - edit.setSelection(length); // 设置光标位置 -} - -public void onEditTextEnter(int index, String text) { - /** - * 如果索引超出 mEditTextList 的范围,应该不会发生,进行调试检查 - */ - if(index > mEditTextList.getChildCount()) { - Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); - } + public void onEditTextDelete(int index, String text) { + int childCount = mEditTextList.getChildCount(); + if (childCount == 1) { + return; + } - // 创建新的编辑框视图并添加到 mEditTextList 中指定的位置 - View view = getListItem(text, index); - mEditTextList.addView(view, index); - NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); - 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); - } -} + for (int i = index + 1; i < childCount; i++) { + ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) + .setIndex(i - 1); + } -// 切换到列表模式的处理方法 -private void switchToListMode(String text) { - // 移除所有的编辑框视图 - mEditTextList.removeAllViews(); - // 将文本按换行符分割成字符串数组 - String[] items = text.split("\n"); - int index = 0; - for (String item : items) { - // 如果项不为空,则创建对应的编辑框视图并添加到 mEditTextList 中 - if(!TextUtils.isEmpty(item)) { - mEditTextList.addView(getListItem(item, index)); - index++; + mEditTextList.removeViewAt(index); + NoteEditText edit = null; + if(index == 0) { + edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( + R.id.et_edit_text); + } else { + edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById( + R.id.et_edit_text); } + int length = edit.length(); + edit.append(text); + edit.requestFocus(); + edit.setSelection(length); } - // 添加一个空的编辑框以便用户继续添加新项 - mEditTextList.addView(getListItem("", index)); - mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); - // 隐藏笔记编辑视图,显示编辑框列表视图 - mNoteEditor.setVisibility(View.GONE); - mEditTextList.setVisibility(View.VISIBLE); -} + 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"); + } -// 获取包含用户查询结果高亮的 Spannable 对象 -private Spannable getHighlightQueryResult(String fullText, String userQuery) { - SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); - if (!TextUtils.isEmpty(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(), - Spannable.SPAN_INCLUSIVE_EXCLUSIVE); - start = m.end(); + View view = getListItem(text, index); + mEditTextList.addView(view, index); + NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + 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); } } - 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); - } else { - // 取消文本删除线 - edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + private void switchToListMode(String text) { + mEditTextList.removeAllViews(); + String[] items = text.split("\n"); + int index = 0; + for (String item : items) { + if(!TextUtils.isEmpty(item)) { + mEditTextList.addView(getListItem(item, index)); + index++; } } - }); - - if (item.startsWith(TAG_CHECKED)) { - // 如果列表项以 "checked" 标识开头,则设置复选框选中状态,设置文本删除线,并去掉标识字符串 - cb.setChecked(true); - edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); - item = item.substring(TAG_CHECKED.length(), item.length()).trim(); - } else if (item.startsWith(TAG_UNCHECKED)) { - // 如果列表项以 "unchecked" 标识开头,则设置复选框未选中状态,取消文本删除线,并去掉标识字符串 - cb.setChecked(false); - edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); - item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); - } + mEditTextList.addView(getListItem("", index)); + mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); + + mNoteEditor.setVisibility(View.GONE); + mEditTextList.setVisibility(View.VISIBLE); + } + + private Spannable getHighlightQueryResult(String fullText, String userQuery) { + SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); + if (!TextUtils.isEmpty(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(), + Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + start = m.end(); + } + } + return spannable; + } + + 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); + } else { + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + } + } + }); - edit.setOnTextViewChangeListener(this); - edit.setIndex(index); - // 设置文本,并将用户查询结果高亮显示 - edit.setText(getHighlightQueryResult(item, mUserQuery)); - return view; -} + if (item.startsWith(TAG_CHECKED)) { + cb.setChecked(true); + edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + item = item.substring(TAG_CHECKED.length(), item.length()).trim(); + } else if (item.startsWith(TAG_UNCHECKED)) { + cb.setChecked(false); + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); + } -/** - * 当文本内容改变时的回调方法 - * @param index 列表项索引 - * @param hasText 是否有文本内容 - */ -public void onTextChange(int index, boolean hasText) { - if (index >= mEditTextList.getChildCount()) { - Log.e(TAG, "Wrong index, should not happen"); - return; + edit.setOnTextViewChangeListener(this); + edit.setIndex(index); + edit.setText(getHighlightQueryResult(item, mUserQuery)); + return view; } - if(hasText) { - // 如果有文本内容,则显示复选框 - mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE); - } else { - // 如果没有文本内容,则隐藏复选框 - mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); + + 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 { + mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); + } } -} -/** - * 当待办事项模式变化时的回调方法 - * @param oldMode 旧的待办事项模式 - * @param newMode 新的待办事项模式 - */ -public void onCheckListModeChanged(int oldMode, int newMode) { - if (newMode == TextNote.MODE_CHECK_LIST) { - // 如果新的模式是待办事项列表模式,则切换到列表模式 - switchToListMode(mNoteEditor.getText().toString()); - } else { - if (!getWorkingText()) { - // 如果工作文本为空,并且未保存的文本中包含 "unchecked" 标识,则将其移除 - mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", "")); + public void onCheckListModeChanged(int oldMode, int newMode) { + if (newMode == TextNote.MODE_CHECK_LIST) { + 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); } - // 设置编辑框内容,并将用户查询结果高亮显示 - mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); - // 隐藏编辑框列表视图,显示笔记编辑视图 - mEditTextList.setVisibility(View.GONE); - mNoteEditor.setVisibility(View.VISIBLE); } -} private boolean getWorkingText() { -/* -这是一个名为 `getWorkingText()` 的私有方法,返回一个布尔值。 -该方法的作用是获取工作文本,具体步骤如下: -1. 首先,检查 `mWorkingNote` 对象的 `CheckListMode` -是否为 `TextNote.MODE_CHECK_LIST`。如果是,则进入列表模式的处理逻辑。 -2. 创建一个 `StringBuilder` 对象 `sb`,用于拼接文本。 -3. 遍历 `mEditTextList` 中的子视图(可能是多个文本编辑框): - - 获取子视图中的 `NoteEditText` 对象,用于获取文本内容。 - - 如果 `edit.getText()` 不为空,表示该文本框有输入内容。 - - 如果相应的复选框 `CheckBox` 被选中(`isChecked()` 返回 `true`), - 将文本设为已选中状态,并向 `sb` 添加标记 `TAG_CHECKED`,文本内容,以及换行符。 - 同时将 `hasChecked` 设为 `true`。 - - 否则,将文本设为未选中状态,并向 `sb` 添加标记 `TAG_UNCHECKED`,文本内容,以及换行符。 -4. 将拼接好的文本 `sb.toString()` 设为 `mWorkingNote` 的工作文本。 -5. 如果 `mWorkingNote` 的 `CheckListMode` 不是 `TextNote.MODE_CHECK_LIST`, -即非列表模式,则将 `mNoteEditor` 的文本内容设为 `mWorkingNote` 的工作文本。 -6. 返回 `hasChecked`,该布尔值表示是否存在已选中的文本项。 - */ boolean hasChecked = false; if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { StringBuilder sb = new StringBuilder(); @@ -1027,7 +796,7 @@ public void onCheckListModeChanged(int oldMode, int newMode) { } return hasChecked; } - + //保存便签 private boolean saveNote() { getWorkingText(); boolean saved = mWorkingNote.saveNote(); @@ -1046,24 +815,9 @@ public void onCheckListModeChanged(int oldMode, int newMode) { private void sendToDesktop() { /** -这段代码实现了一个名为 `sendToDesktop()` 的方法,用于将当前编辑的笔记发送到桌面上。 -以下是对该方法的解释: -1. 首先,检查当前编辑的笔记 `mWorkingNote` 是否存在于数据库中。 -如果笔记在数据库中不存在(即为新笔记),则调用 `saveNote()` 方法保存笔记。 -2. 如果当前编辑的笔记已经存在于数据库中(即为已有的笔记),执行以下操作: - - 创建一个 `Intent` 对象 `sender`。 - - 创建一个 `Intent` 对象 `shortcutIntent`,指定其启动目标为 `NoteEditActivity` 类。 - - 为 `shortcutIntent` 指定动作 `Intent.ACTION_VIEW`,表示要进行查看操作。 - - 通过 `putExtra()` 方法向 `shortcutIntent` 传递附加信息,包括笔记的唯一标识符(`NoteId`)。 - - 通过 `sender.putExtra()` 方法向 `sender` 传递附加信息,包括快捷方式的意图(`shortcutIntent`)、 - 快捷方式的名称、快捷方式的图标资源和重复安装的标志等。 - - 通过设置 `sender` 的动作为 `"com.android.launcher.action.INSTALL_SHORTCUT"`,表示要安装快捷方式。 - - 调用 `showToast()` 方法显示一个消息提示框,提示用户笔记已进入桌面。 - - 调用 `sendBroadcast()` 方法发送广播,通知系统安装快捷方式。 -3. 如果当前编辑的笔记不存在(即为没有输入内容的空笔记), -则记录一个错误日志并调用 `showToast()` 方法显示一个错误提示框,提醒用户输入内容。 -4. 方法执行结束。 -综上,该方法的功能是将当前编辑的笔记发送到桌面上,并根据笔记的状态进行相应的处理,如保存新笔记、创建快捷方式等。 + * 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(); @@ -1095,21 +849,17 @@ public void onCheckListModeChanged(int oldMode, int newMode) { } private String makeShortcutIconTitle(String content) { - // 将原始内容中的特定字符串替换为空字符串,以删除特定标记 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; + return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0, + SHORTCUT_ICON_TITLE_MAX_LEN) : content; } - + private void showToast(int resId) { - // 显示一个短持续时间的Toast消息,消息内容为给定的资源ID的字符串 showToast(resId, Toast.LENGTH_SHORT); } - + private void showToast(int resId, int duration) { - // 显示一个具有自定义持续时间的Toast消息,消息内容为给定的资源ID的字符串 - // Toast消息在当前的上下文中显示 Toast.makeText(this, resId, duration).show(); } }