diff --git a/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java index e52ad57..e3c2eb4 100644 --- a/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -7,98 +7,95 @@ * * 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; // 定义包名,表示该类文件位于net.micode.notes.ui这个包中 - -import java.util.Calendar; // 导入Java的Calendar类,用于操作日期和时间 - -import net.micode.notes.R; // 导入R资源文件,用于访问应用中的资源 -import net.micode.notes.ui.DateTimePicker; // 导入自定义的日期时间选择器控件 -import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; // 导入日期时间选择器控件的监听器接口 - -import android.app.AlertDialog; // 导入Android的AlertDialog类,用于创建对话框 -import android.content.Context; // 导入Android的Context类,用于访问系统资源 -import android.content.DialogInterface; // 导入Android的DialogInterface类,用于处理对话框中的按钮点击事件 -import android.content.DialogInterface.OnClickListener; // 导入DialogInterface的OnClickListener接口 -import android.text.format.DateFormat; // 导入Android的DateFormat工具类,用于格式化日期和时间 -import android.text.format.DateUtils; // 导入Android的DateUtils工具类,用于处理日期和时间相关的操作 - + +package net.micode.notes.ui; + +import java.util.Calendar; + +import net.micode.notes.R; +import net.micode.notes.ui.DateTimePicker; +import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.text.format.DateFormat; +import android.text.format.DateUtils; + // 自定义的日期时间选择对话框,继承自AlertDialog并实现了OnClickListener接口 public class DateTimePickerDialog extends AlertDialog implements OnClickListener { - + // 存储当前选择的日期时间 - private Calendar mDate = Calendar.getInstance(); // 创建一个Calendar实例,初始化为当前时间 - + private Calendar mDate = Calendar.getInstance(); // 是否使用24小时制 - private boolean mIs24HourView; // 布尔变量,用于判断是否使用24小时制显示时间 - + private boolean mIs24HourView; // 回调接口,当日期时间设置完成后调用 - private OnDateTimeSetListener mOnDateTimeSetListener; // 定义一个回调接口,当用户选择好日期时间后进行回调 - + private OnDateTimeSetListener mOnDateTimeSetListener; // 日期时间选择器控件 - private DateTimePicker mDateTimePicker; // 定义一个日期时间选择器控件实例,用于在对话框中选择日期时间 - + private DateTimePicker mDateTimePicker; + // 定义日期时间设置完成后的回调接口 public interface OnDateTimeSetListener { - void OnDateTimeSet(AlertDialog dialog, long date); // 定义回调方法,传入当前对话框和选择的日期时间(long类型) + void OnDateTimeSet(AlertDialog dialog, long date); } - + // 构造函数,初始化对话框并设置初始日期时间 public DateTimePickerDialog(Context context, long date) { - super(context); // 调用父类AlertDialog的构造函数,传入上下文环境 - mDateTimePicker = new DateTimePicker(context); // 创建日期时间选择器控件实例 - setView(mDateTimePicker); // 将日期时间选择器控件添加到对话框中 - mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { // 设置日期时间选择器控件的监听器 - public void onDateTimeChanged(DateTimePicker view, int year, int month, // 定义监听器回调方法,当日期时间发生变化时调用 + super(context); + mDateTimePicker = new DateTimePicker(context); + setView(mDateTimePicker); + mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { + public void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute) { - mDate.set(Calendar.YEAR, year); // 更新mDate中的年份为选择的年份 - mDate.set(Calendar.MONTH, month); // 更新mDate中的月份为选择的月份 - mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); // 更新mDate中的日期为选择的日期 - mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); // 更新mDate中的小时为选择的小时 - mDate.set(Calendar.MINUTE, minute); // 更新mDate中的分钟为选择的分钟 - mDate.set(Calendar.SECOND, 0); // 将秒设置为0,忽略秒的选择 - updateTitle(mDate.getTimeInMillis()); // 更新对话框标题,显示当前选择的日期时间 + mDate.set(Calendar.YEAR, year); + mDate.set(Calendar.MONTH, month); + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + mDate.set(Calendar.MINUTE, minute); + updateTitle(mDate.getTimeInMillis()); } }); - mDate.setTimeInMillis(date); // 将mDate设置为传入的初始日期时间 - mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); // 将日期时间选择器控件的当前日期时间设置为传入的初始日期时间 - setButton(context.getString(R.string.datetime_dialog_ok), this); // 设置确认按钮,按钮文本为资源文件中的"datetime_dialog_ok"定义的文本,点击事件为当前类 - setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); // 设置取消按钮,按钮文本为资源文件中的"datetime_dialog_cancel"定义的文本,点击事件为空 - set24HourView(DateFormat.is24HourFormat(this.getContext())); // 根据系统设置判断是否使用24小时制显示时间 - updateTitle(mDate.getTimeInMillis()); // 更新对话框标题,显示初始选择的日期时间 + mDate.setTimeInMillis(date); + mDate.set(Calendar.SECOND, 0); + mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); + setButton(context.getString(R.string.datetime_dialog_ok), this); + setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); + set24HourView(DateFormat.is24HourFormat(this.getContext())); + updateTitle(mDate.getTimeInMillis()); } - + // 设置是否使用24小时制显示时间 public void set24HourView(boolean is24HourView) { - mIs24HourView = is24HourView; // 更新是否使用24小时制的布尔值 + mIs24HourView = is24HourView; } - + // 设置日期时间选择完成后的回调监听器 public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { - mOnDateTimeSetListener = callBack; // 设置回调监听器为传入的参数 + mOnDateTimeSetListener = callBack; } - + // 更新对话框的标题以显示当前选择的日期时间 private void updateTitle(long date) { int flag = - DateUtils.FORMAT_SHOW_YEAR | // 格式化标志,显示年份 - DateUtils.FORMAT_SHOW_DATE | // 格式化标志,显示日期 - DateUtils.FORMAT_SHOW_TIME; // 格式化标志,显示时间 - flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_12HOUR; // 根据是否使用24小时制添加相应的格式化标志 - setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); // 使用DateUtils.formatDateTime方法格式化日期时间,并设置为对话框的标题 + DateUtils.FORMAT_SHOW_YEAR | + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; + flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; + setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); } - + // 处理用户点击对话框按钮的事件,如果是确认按钮则调用回调监听器 public void onClick(DialogInterface arg0, int arg1) { - if (mOnDateTimeSetListener != null) { // 检查回调监听器是否为空 - mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); // 调用回调监听器的OnDateTimeSet方法,传入当前对话框和选择的日期时间 + if (mOnDateTimeSetListener != null) { + mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } } - -} + +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java index c2e2ab6..3e45406 100644 --- a/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java +++ b/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package net.micode.notes.ui; - + import android.app.Activity; import android.app.AlarmManager; import android.app.AlertDialog; @@ -51,7 +51,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; - + import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.TextNote; @@ -64,646 +64,591 @@ import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener; import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener; import net.micode.notes.widget.NoteWidgetProvider_2x; import net.micode.notes.widget.NoteWidgetProvider_4x; - + import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; - + // 笔记编辑界面的Activity类 public class NoteEditActivity extends Activity implements OnClickListener, NoteSettingChangedListener, OnTextViewChangeListener { // 用于存储笔记头部视图的ViewHolder类 private class HeadViewHolder { - public TextView tvModified; // 显示笔记修改日期的TextView - - public ImageView ivAlertIcon; // 显示提醒图标的ImageView - - public TextView tvAlertDate; // 显示提醒日期的TextView - - public ImageView ibSetBgColor; // 设置背景颜色的按钮 - } - + public TextView tvModified; + + public ImageView ivAlertIcon; + + public TextView tvAlertDate; + + public ImageView ibSetBgColor; + } + // 背景色选择按钮和颜色ID的映射 private static final Map sBgSelectorBtnsMap = new HashMap(); static { - sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); // 黄色按钮对应的颜色ID - sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED); // 红色按钮对应的颜色ID - sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE); // 蓝色按钮对应的颜色ID - sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN); // 绿色按钮对应的颜色ID - sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); // 白色按钮对应的颜色ID + sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); + sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED); + sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE); + sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN); + sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); } - + // 背景色选择后的显示标记和颜色ID的映射 private static final Map sBgSelectorSelectionMap = new HashMap(); static { - sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); // 黄色选择标记对应的ID - sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select); // 红色选择标记对应的ID - sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select); // 蓝色选择标记对应的ID - sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select); // 绿色选择标记对应的ID - sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); // 白色选择标记对应的ID + sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); + sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select); + sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select); + sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select); + sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); } - + // 字体大小选择按钮和字体大小ID的映射 private static final Map sFontSizeBtnsMap = new HashMap(); static { - sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); // 大字体按钮对应的字体ID - sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); // 小字体按钮对应的字体ID - sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM); // 中字体按钮对应的字体ID - sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); // 超大字体按钮对应的字体ID + sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); + sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); + sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM); + sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); } - + // 字体大小选择后的显示标记和字体大小ID的映射 private static final Map sFontSelectorSelectionMap = new HashMap(); static { - sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); // 大字体选择标记对应的ID - sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); // 小字体选择标记对应的ID - sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); // 中字体选择标记对应的ID - sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); // 超大字体选择标记对应的ID - } - - private static final String TAG = "NoteEditActivity"; // 日志标签 - - 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; // 共享preferences对象,用于存储用户偏好设置 - 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; // 存储多个NoteEditText的LinearLayout - - private String mUserQuery; // 用户搜索查询的字符串 - private Pattern mPattern; // 用于匹配查询字符串的正则表达式模式 - + sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); + } + + 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; + // 初始化Activity视图 @Override protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); // 永远调用父类的onCreate方法 - this.setContentView(R.layout.note_edit); // 设置布局文件为note_edit.xml - - // 如果是首次创建且initActivityState失败,则直接关闭Activity + super.onCreate(savedInstanceState); + this.setContentView(R.layout.note_edit); + if (savedInstanceState == null && !initActivityState(getIntent())) { finish(); return; } - initResources(); // 初始化视图资源 + initResources(); } - + // 当Activity被系统杀死后,恢复其状态 @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); // 永远调用父类的onRestoreInstanceState方法 - // 如果savedInstanceState不为空且包含Intent.EXTRA_UID键,则重新加载笔记 + super.onRestoreInstanceState(savedInstanceState); if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID)); if (!initActivityState(intent)) { - finish(); // 如果initActivityState失败,则关闭Activity + finish(); return; } - Log.d(TAG, "Restoring from killed activity"); // 记录日志 + Log.d(TAG, "Restoring from killed activity"); } } - + // 初始化Activity状态,根据Intent决定加载笔记或创建新笔记 private boolean initActivityState(Intent intent) { - mWorkingNote = null; // 初始化笔记对象为null - // 如果Intent动作是ACTION_VIEW,则加载指定笔记 + mWorkingNote = null; if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { - long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); // 获取笔记ID - mUserQuery = ""; // 初始化用户查询字符串为空 - - // 如果Intent包含SearchManager.EXTRA_DATA_KEY,则从搜索结果中加载笔记 + long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); + mUserQuery = ""; + if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) { - noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); // 获取笔记ID - mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); // 获取用户查询字符串 + 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); showToast(R.string.error_note_not_exist); finish(); return false; } else { - mWorkingNote = WorkingNote.load(this, noteId); // 加载指定笔记 - if (mWorkingNote == null) { // 如果加载失败,则显示错误信息并关闭Activity + mWorkingNote = WorkingNote.load(this, noteId); + if (mWorkingNote == null) { Log.e(TAG, "load note failed with note id" + noteId); finish(); 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())) { // 如果Intent动作是ACTION_INSERT_OR_EDIT,则创建新笔记或编辑现有笔记 - long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); // 获取文件夹ID + } 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); // 获取小部件ID + AppWidgetManager.INVALID_APPWIDGET_ID); int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, - Notes.TYPE_WIDGET_INVALIDE); // 获取小部件类型 + Notes.TYPE_WIDGET_INVALIDE); int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, - ResourceParser.getDefaultBgId(this)); // 获取背景颜色资源ID - - String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); // 获取电话号码(对于通话记录笔记) - long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); // 获取通话日期(对于通话记录笔记) - if (callDate != 0 && phoneNumber != null) { // 如果通话日期和电话号码都存在,则尝试加载通话记录笔记 + ResourceParser.getDefaultBgId(this)); + + String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); + long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); + if (callDate != 0 && phoneNumber != null) { if (TextUtils.isEmpty(phoneNumber)) { - Log.w(TAG, "The call record number is null"); // 日志警告 + Log.w(TAG, "The call record number is null"); } long noteId = 0; - // 根据电话号码和通话日期查找笔记ID if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(), phoneNumber, callDate)) > 0) { - mWorkingNote = WorkingNote.load(this, noteId); // 加载指定笔记 - if (mWorkingNote == null) { // 如果加载失败,则显示错误信息并关闭Activity + mWorkingNote = WorkingNote.load(this, noteId); + if (mWorkingNote == null) { Log.e(TAG, "load call note failed with note id" + noteId); finish(); return false; } - } else { // 如果笔记不存在,则创建新笔记并转换为通话记录笔记 + } else { mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); mWorkingNote.convertToCallNote(phoneNumber, callDate); } - } else { // 如果通话日期或电话号码不存在,则创建新笔记 + } 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动作不支持,则显示错误信息并关闭Activity + } else { Log.e(TAG, "Intent not specified action, should not support"); finish(); return false; } - mWorkingNote.setOnSettingStatusChangedListener(this); // 设置笔记配置变化监听器 - return true; // 返回true表示初始化成功 + mWorkingNote.setOnSettingStatusChangedListener(this); + return true; } - + // Activity恢复时初始化笔记显示 @Override protected void onResume() { - super.onResume(); // 永远调用父类的onResume方法 - initNoteScreen(); // 初始化笔记显示界面 + super.onResume(); + 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.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + 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)); // 显示年份 - - showAlertHeader(); // 显示或隐藏提醒头部信息 - } - + + mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this, + mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_YEAR)); + + showAlertHeader(); + } + // 显示或隐藏提醒头部信息 private void showAlertHeader() { - // 如果笔记设置了警报 if (mWorkingNote.hasClockAlert()) { - long time = System.currentTimeMillis(); // 获取当前时间 - // 如果当前时间大于警报时间,则显示警报已过期,否则显示相对时间 + long time = System.currentTimeMillis(); if (time > mWorkingNote.getAlertDate()) { mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); } else { - mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( // 获取相对时间字符串 + 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.VISIBLE); + mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); + } else { mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); }; } - + // 处理新的Intent,可能需要重新加载笔记或创建新笔记 @Override protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); // 永远调用父类的onNewIntent方法 - initActivityState(intent); // 初始化Activity状态 + super.onNewIntent(intent); + initActivityState(intent); } - + // 保存Activity状态,在系统需要恢复Activity时使用 @Override protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); // 永远调用父类的onSaveInstanceState方法 - // 如果笔记不存在于数据库中,则保存笔记 + super.onSaveInstanceState(outState); if (!mWorkingNote.existInDatabase()) { saveNote(); } - outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); // 保存笔记ID - Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); // 记录日志 + outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + 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); return true; } - - // 如果字体大小选择面板可见且触摸事件不在面板范围内,则隐藏面板 + if (mFontSizeSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mFontSizeSelector, ev)) { mFontSizeSelector.setVisibility(View.GONE); return true; } - return super.dispatchTouchEvent(ev); // 其他情况,调用父类的方法 + return super.dispatchTouchEvent(ev); } - + // 判断触摸事件是否发生在指定视图内 private boolean inRangeOfView(View view, MotionEvent ev) { int []location = new int[2]; - view.getLocationOnScreen(location); // 获取视图在屏幕上的位置 - int x = location[0]; // 获取视图左上角x坐标 - int y = location[1]; // 获取视图左上角y坐标 - // 判断触摸点是否在视图范围内 + view.getLocationOnScreen(location); + int x = location[0]; + int y = location[1]; if (ev.getX() < x - || ev.getX() > (x + view.getWidth()) // 触摸点x坐标小于视图左边界或大于视图右边界 + || ev.getX() > (x + view.getWidth()) || ev.getY() < y - || ev.getY() > (y + view.getHeight())) { // 触摸点y坐标小于视图上边界或大于视图下边界 - return false; // 返回false表示触摸点不在视图范围内 + || ev.getY() > (y + view.getHeight())) { + return false; } - return true; // 返回true表示触摸点在视图范围内 + return true; } - + // 初始化视图资源 private void initResources() { - mHeadViewPanel = findViewById(R.id.note_title); // 获取头部视图面板 - mNoteHeaderHolder = new HeadViewHolder(); // 创建ViewHolder对象 - mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date); // 获取修改日期TextView - mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon); // 获取警报图标ImageView - mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date); // 获取警报日期TextView - 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()) { // 为背景颜色选择按钮设置点击监听器 + 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); } - - mFontSizeSelector = findViewById(R.id.font_size_selector); // 获取字体大小选择面板 - for (int id : sFontSizeBtnsMap.keySet()) { // 为字体大小选择按钮设置点击监听器 + + mFontSizeSelector = findViewById(R.id.font_size_selector); + for (int id : sFontSizeBtnsMap.keySet()) { View view = findViewById(id); view.setOnClickListener(this); }; - mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); // 获取默认SharedPreferences对象 - mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); // 获取用户选择的字体大小ID - // 如果字体大小ID超出范围,则使用默认字体大小 + mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; } - mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); // 获取NoteEditText列表 + mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); } - + // 暂停Activity时保存笔记并清理设置状态 @Override protected void onPause() { - super.onPause(); // 永远调用父类的onPause方法 - // 保存笔记内容到数据库,如果成功则记录日志 + super.onPause(); 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); // 创建更新小部件的Intent - // 根据小部件类型设置Intent的类 + 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"); // 日志错误 + Log.e(TAG, "Unspported widget type"); return; } - - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { // 添加小部件ID + + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { mWorkingNote.getWidgetId() }); - - sendBroadcast(intent); // 发送广播更新小部件 - setResult(RESULT_OK, intent); // 设置Activity结果 + + sendBroadcast(intent); + setResult(RESULT_OK, intent); } - + // 处理视图点击事件,包括颜色和字体大小选择 public void onClick(View v) { - int id = v.getId(); // 获取点击视图的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)) { // 如果点击的是背景颜色选择按钮 - // 隐藏之前选择的背景颜色标记 + } else if (sBgSelectorBtnsMap.containsKey(id)) { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.GONE); - mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id)); // 设置新的背景颜色ID - mNoteBgColorSelector.setVisibility(View.GONE); // 隐藏背景颜色选择面板 - } else if (sFontSizeBtnsMap.containsKey(id)) { // 如果点击的是字体大小选择按钮 - // 隐藏之前选择的字体大小标记 + 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); // 设置新的字体大小ID - // 将新的字体大小ID保存到SharedPreferences中 + 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()); // 切换到列表模式 + getWorkingText(); + switchToListMode(mWorkingNote.getContent()); } else { - mNoteEditor.setTextAppearance(this, // 设置文本外观 + mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); } - mFontSizeSelector.setVisibility(View.GONE); // 隐藏字体大小选择面板 + mFontSizeSelector.setVisibility(View.GONE); } } - + // 处理返回键事件,如果设置面板可见则隐藏,否则保存笔记后返回 @Override public void onBackPressed() { - // 如果设置面板可见,则隐藏并返回 if(clearSettingState()) { return; } - - saveNote(); // 保存笔记内容到数据库 - super.onBackPressed(); // 调用父类的onBackPressed方法 + + saveNote(); + super.onBackPressed(); } - + // 清理设置面板状态 private boolean clearSettingState() { - // 如果背景颜色选择面板可见,则隐藏并返回true if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { mNoteBgColorSelector.setVisibility(View.GONE); return true; - } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) { // 如果字体大小选择面板可见,则隐藏并返回true + } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) { mFontSizeSelector.setVisibility(View.GONE); return true; } - return false; // 如果两个面板都不可见,则返回false + return false; } - + // 处理笔记背景颜色变化事件 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()) { // 如果Activity正在结束,则返回true + if (isFinishing()) { return true; } - clearSettingState(); // 清理设置面板状态 - menu.clear(); // 清空菜单项 - // 根据笔记所在的文件夹ID动态更新菜单项 + clearSettingState(); + menu.clear(); if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) { - getMenuInflater().inflate(R.menu.call_note_edit, menu); // 加载通话记录笔记编辑菜单 + getMenuInflater().inflate(R.menu.call_note_edit, menu); } else { - getMenuInflater().inflate(R.menu.note_edit, menu); // 加载普通笔记编辑菜单 + 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); // 设置为普通模式 + 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); // 设置为列表模式 + menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode); } - // 根据笔记是否设置了警报动态更新菜单项可见性 if (mWorkingNote.hasClockAlert()) { - menu.findItem(R.id.menu_alert).setVisible(false); // 隐藏设置警报菜单项 + menu.findItem(R.id.menu_alert).setVisible(false); } else { - menu.findItem(R.id.menu_delete_remind).setVisible(false); // 隐藏删除警报菜单项 + menu.findItem(R.id.menu_delete_remind).setVisible(false); } - return true; // 返回true表示菜单项已准备好 + return true; } - + // 处理选项菜单项点击事件 @Override public boolean onOptionsItemSelected(MenuItem item) { - // 根据菜单项ID执行相应操作 switch (item.getItemId()) { case R.id.menu_new_note: - createNewNote(); // 创建新笔记 + createNewNote(); break; case 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, // 设置确定按钮 + 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(); // 关闭Activity + deleteCurrentNote(); + finish(); } }); - builder.setNegativeButton(android.R.string.cancel, null); // 设置取消按钮 - builder.show(); // 显示对话框 + builder.setNegativeButton(android.R.string.cancel, null); + 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; // 默认情况,不做任何操作 + break; } - return true; // 返回true表示菜单项点击事件已处理 + return true; } - + // 设置提醒时间 private void setReminder() { - // 创建DateTimePickerDialog对象,设置初始时间为当前时间 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(); // 显示日期时间选择对话框 + d.show(); } - + // 分享笔记内容到支持ACTION_SEND的其他应用 private void sendTo(Context context, String info) { - Intent intent = new Intent(Intent.ACTION_SEND); // 创建ACTION_SEND Intent - intent.putExtra(Intent.EXTRA_TEXT, info); // 添加文本内容 - intent.setType("text/plain"); // 设置类型为纯文本 - context.startActivity(intent); // 启动Intent + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, info); + intent.setType("text/plain"); + context.startActivity(intent); } - + // 创建新笔记,跳转到新笔记编辑界面 private void createNewNote() { - saveNote(); // 保存当前笔记内容 - - finish(); // 关闭当前Activity - Intent intent = new Intent(this, NoteEditActivity.class); // 创建新笔记编辑Activity的Intent - intent.setAction(Intent.ACTION_INSERT_OR_EDIT); // 设置Intent动作为插入或编辑笔记 - intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId()); // 添加文件夹ID - startActivity(intent); // 启动新笔记编辑Activity - } - + saveNote(); + + finish(); + 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); + } + // 删除当前笔记 private void deleteCurrentNote() { - // 如果笔记存在于数据库中 if (mWorkingNote.existInDatabase()) { HashSet ids = new HashSet(); - long id = mWorkingNote.getNoteId(); // 获取笔记ID - // 如果笔记ID不是根文件夹ID,则添加到要删除的ID集合中 + long id = mWorkingNote.getNoteId(); if (id != Notes.ID_ROOT_FOLDER) { ids.add(id); } else { - Log.d(TAG, "Wrong note id, should not happen"); // 日志错误 + Log.d(TAG, "Wrong note id, should not happen"); } - // 根据是否处于同步模式决定删除或移动到回收站 if (!isSyncMode()) { - if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { // 批量删除笔记 - Log.e(TAG, "Delete Note error"); // 日志错误 + if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { + Log.e(TAG, "Delete Note error"); } } else { - if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) { // 批量移动到回收站 - Log.e(TAG, "Move notes to trash folder error, should not happens"); // 日志错误 + if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) { + Log.e(TAG, "Move notes to trash folder error, should not happens"); } } } - mWorkingNote.markDeleted(true); // 标记笔记已删除 + mWorkingNote.markDeleted(true); } - + // 判断是否处于同步模式 private boolean isSyncMode() { - // 获取同步账户名称,如果非空则返回true,否则返回false return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } - + // 处理时钟提醒变化事件,设置或取消提醒 public void onClockAlertChanged(long date, boolean set) { - // 如果笔记不存在于数据库中,则保存笔记 if (!mWorkingNote.existInDatabase()) { saveNote(); } - // 如果笔记ID大于0 if (mWorkingNote.getNoteId() > 0) { - Intent intent = new Intent(this, AlarmReceiver.class); // 创建AlarmReceiver Intent - // 添加笔记URI到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) getSystemService(ALARM_SERVICE)); // 获取AlarmManager对象 - showAlertHeader(); // 显示或隐藏提醒头部信息 - // 如果设置为取消提醒,则取消Alarm;否则设置新的Alarm + AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); + showAlertHeader(); if(!set) { alarmManager.cancel(pendingIntent); } else { alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); } - } else { // 如果笔记ID无效,则显示错误信息 + } else { Log.e(TAG, "Clock alert setting error"); showToast(R.string.error_note_empty_for_clock); } } - + // 处理小部件变化事件,更新小部件显示 public void onWidgetChanged() { - updateWidget(); // 更新小部件显示 + updateWidget(); } - + // 处理EditText删除事件,调整列表项索引 public void onEditTextDelete(int index, String text) { - int childCount = mEditTextList.getChildCount(); // 获取NoteEditText子视图数量 - // 如果只有一个NoteEditText,则不做任何操作 + int childCount = mEditTextList.getChildCount(); if (childCount == 1) { return; } - - // 调整删除位置之后的NoteEditText索引 + for (int i = index + 1; i < childCount; i++) { ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) .setIndex(i - 1); } - - mEditTextList.removeViewAt(index); // 删除指定位置的NoteEditText + + mEditTextList.removeViewAt(index); NoteEditText edit = null; - // 根据删除位置获取新的NoteEditText对象 if(index == 0) { edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( R.id.et_edit_text); @@ -711,219 +656,200 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById( R.id.et_edit_text); } - int length = edit.length(); // 获取NoteEditText的文本长度 - edit.append(text); // 将删除的文本追加到新的NoteEditText对象中 - edit.requestFocus(); // 设置焦点到新的NoteEditText对象 - edit.setSelection(length); // 设置光标位置到追加文本之前 + int length = edit.length(); + edit.append(text); + edit.requestFocus(); + edit.setSelection(length); } - + // 处理EditText输入事件,添加新列表项 public void onEditTextEnter(int index, String text) { - // 如果索引超出范围,则记录错误日志 if(index > mEditTextList.getChildCount()) { Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); } - - View view = getListItem(text, index); // 创建新的NoteEditText视图 - mEditTextList.addView(view, index); // 将新的视图添加到指定位置 - NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); // 获取NoteEditText对象 - edit.requestFocus(); // 设置焦点到新的NoteEditText对象 - edit.setSelection(0); // 设置光标位置到文本开头 - // 调整新添加NoteEditText之后的NoteEditText索引 + + 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); } } - + // 切换到列表模式,根据笔记内容生成列表项 private void switchToListMode(String text) { - mEditTextList.removeAllViews(); // 移除所有NoteEditText视图 - String[] items = text.split("\n"); // 将笔记内容按换行符分割成多个项 + mEditTextList.removeAllViews(); + String[] items = text.split("\n"); int index = 0; - // 遍历每一项,创建并添加NoteEditText视图 for (String item : items) { - if(!TextUtils.isEmpty(item)) { // 如果项不为空 - mEditTextList.addView(getListItem(item, index)); // 添加NoteEditText视图 - index++; // 索引加1 + if(!TextUtils.isEmpty(item)) { + mEditTextList.addView(getListItem(item, index)); + index++; } } - mEditTextList.addView(getListItem("", index)); // 添加一个空的NoteEditText视图 - // 设置焦点到新添加的NoteEditText对象 + mEditTextList.addView(getListItem("", index)); mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); - - mNoteEditor.setVisibility(View.GONE); // 隐藏编辑框 - mEditTextList.setVisibility(View.VISIBLE); // 显示NoteEditText列表 + + mNoteEditor.setVisibility(View.GONE); + mEditTextList.setVisibility(View.VISIBLE); } - + // 获取高亮查询结果,用于显示搜索关键词 private Spannable getHighlightQueryResult(String fullText, String userQuery) { - SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); // 创建SpannableString对象 - if (!TextUtils.isEmpty(userQuery)) { // 如果用户查询字符串不为空 - mPattern = Pattern.compile(userQuery); // 编译正则表达式模式 - Matcher m = mPattern.matcher(fullText); // 创建Matcher对象 + 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(), // 设置背景颜色标记 + R.color.user_query_highlight)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); start = m.end(); } } - return spannable; // 返回高亮搜索结果 + return spannable; } - + // 生成一个新的列表项视图 private View getListItem(String item, int index) { - View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); // 创建NoteEditText视图 - final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); // 获取NoteEditText对象 - edit.setTextAppearance(this, // 设置文本外观 - TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); - CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item)); // 获取CheckBox对象 - // 设置CheckBox的点击监听器 + 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); } } }); - - // 根据项内容设置CheckBox状态 + if (item.startsWith(TAG_CHECKED)) { - cb.setChecked(true); // 设置CheckBox为勾选状态 - edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); // 设置文本划线 - item = item.substring(TAG_CHECKED.length(), item.length()).trim(); // 去掉勾选标签 + 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); // 设置CheckBox为未勾选状态 - edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); // 清除文本划线 - item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); // 去掉未勾选标签 + cb.setChecked(false); + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); } - - edit.setOnTextViewChangeListener(this); // 设置文本变化监听器 - edit.setIndex(index); // 设置索引 - edit.setText(getHighlightQueryResult(item, mUserQuery)); // 设置文本并高亮搜索关键词 - return view; // 返回生成的NoteEditText视图 + + edit.setOnTextViewChangeListener(this); + edit.setIndex(index); + edit.setText(getHighlightQueryResult(item, mUserQuery)); + return view; } - + // 处理EditText文本变化事件,显示或隐藏复选框 public void onTextChange(int index, boolean hasText) { - // 如果索引超出范围,则记录错误日志 if (index >= mEditTextList.getChildCount()) { Log.e(TAG, "Wrong index, should not happen"); return; } - // 根据文本内容显示或隐藏CheckBox 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 onCheckListModeChanged(int oldMode, int newMode) { - // 如果新模式是检查列表模式,则切换到列表模式 if (newMode == TextNote.MODE_CHECK_LIST) { switchToListMode(mNoteEditor.getText().toString()); - } else { // 如果新模式不是检查列表模式,则切换到普通模式 - // 如果不是检查列表模式,则从内容中移除检查列表标签 + } else { if (!getWorkingText()) { mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", "")); } - mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); // 设置编辑框文本并高亮搜索关键词 - mEditTextList.setVisibility(View.GONE); // 隐藏NoteEditText列表 - mNoteEditor.setVisibility(View.VISIBLE); // 显示编辑框 + mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + mEditTextList.setVisibility(View.GONE); + mNoteEditor.setVisibility(View.VISIBLE); } } - + // 获取正在编辑的文本内容,根据列表模式添加标签 private boolean getWorkingText() { - boolean hasChecked = false; // 是否有勾选项 - // 如果笔记处于检查列表模式,则从列表项中获取文本内容,并添加标签 + boolean hasChecked = false; if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { StringBuilder sb = new StringBuilder(); - // 遍历NoteEditText列表项 for (int i = 0; i < mEditTextList.getChildCount(); i++) { - View view = mEditTextList.getChildAt(i); // 获取NoteEditText视图 - NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); // 获取NoteEditText对象 - // 如果NoteEditText文本不为空,则根据CheckBox状态添加标签 + View view = mEditTextList.getChildAt(i); + NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); if (!TextUtils.isEmpty(edit.getText())) { - // 如果CheckBox被勾选,则添加勾选标签,并设置文本划线 if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) { sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n"); hasChecked = true; - } else { // 如果CheckBox未被勾选,则添加未勾选标签 + } else { sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n"); } } } - mWorkingNote.setWorkingText(sb.toString()); // 设置正在编辑的文本内容 - } else { // 如果笔记不是检查列表模式,则直接设置文本内容 + mWorkingNote.setWorkingText(sb.toString()); + } else { mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); } - return hasChecked; // 返回是否有勾选项 + return hasChecked; } - + // 保存笔记内容到数据库 private boolean saveNote() { - getWorkingText(); // 获取正在编辑的文本内容 - boolean saved = mWorkingNote.saveNote(); // 保存笔记 - if (saved) { // 如果保存成功,则设置Activity结果为RESULT_OK + getWorkingText(); + boolean saved = mWorkingNote.saveNote(); + if (saved) { setResult(RESULT_OK); } - return saved; // 返回保存结果 + return saved; } - + // 将笔记快捷方式添加到桌面 private void sendToDesktop() { - // 如果笔记不存在于数据库中,则保存笔记 if (!mWorkingNote.existInDatabase()) { saveNote(); } - - // 如果笔记ID大于0 + if (mWorkingNote.getNoteId() > 0) { - Intent sender = new Intent(); // 创建Intent对象 - Intent shortcutIntent = new Intent(this, NoteEditActivity.class); // 创建快捷方式Intent - shortcutIntent.setAction(Intent.ACTION_VIEW); // 设置Intent动作为ACTION_VIEW - shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); // 添加笔记ID - sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); // 添加快捷方式Intent - sender.putExtra(Intent.EXTRA_SHORTCUT_NAME, // 设置快捷方式名称 + Intent sender = new Intent(); + Intent shortcutIntent = new Intent(this, NoteEditActivity.class); + shortcutIntent.setAction(Intent.ACTION_VIEW); + shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + sender.putExtra(Intent.EXTRA_SHORTCUT_NAME, makeShortcutIconTitle(mWorkingNote.getContent())); - sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, // 添加快捷方式图标 + 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"); // 设置Intent动作为安装快捷方式 - showToast(R.string.info_note_enter_desktop); // 显示提示信息 - sendBroadcast(sender); // 发送安装快捷方式的广播 - } else { // 如果笔记ID无效,则显示错误信息 + sender.putExtra("duplicate", true); + sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); + showToast(R.string.info_note_enter_desktop); + sendBroadcast(sender); + } else { Log.e(TAG, "Send to desktop error"); showToast(R.string.error_note_empty_for_send_to_desktop); } } - + // 生成桌面快捷方式的标题,截取笔记内容的一部分作为标题 private String makeShortcutIconTitle(String content) { - content = content.replace(TAG_CHECKED, ""); // 移除勾选标签 - content = content.replace(TAG_UNCHECKED, ""); // 移除未勾选标签 - // 如果内容长度大于最大长度,则截取前10个字符作为标题;否则直接使用内容作为标题 + 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; } - + // 显示短Toast消息 private void showToast(int resId) { - showToast(resId, Toast.LENGTH_SHORT); // 调用另一个showToast方法,设置Toast显示时间为短时间 + showToast(resId, Toast.LENGTH_SHORT); } - + // 显示指定持续时间的Toast消息 private void showToast(int resId, int duration) { - Toast.makeText(this, resId, duration).show(); // 显示Toast消息 + Toast.makeText(this, resId, duration).show(); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NoteEditText.java b/Notes-master/src/net/micode/notes/ui/NoteEditText.java index beaee55..d350c57 100644 --- a/Notes-master/src/net/micode/notes/ui/NoteEditText.java +++ b/Notes-master/src/net/micode/notes/ui/NoteEditText.java @@ -7,9 +7,11 @@ * * 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; @@ -37,15 +39,14 @@ import java.util.Map; // 自定义的EditText,用于笔记应用中,支持删除、添加文本事件监听 public class NoteEditText extends EditText { - private static final String TAG = "NoteEditText"; // 日志标签 - private int mIndex; // 当前文本框的索引 - private int mSelectionStartBeforeDelete; // 记录删除操作前的光标位置 + private static final String TAG = "NoteEditText"; + private int mIndex; + private int mSelectionStartBeforeDelete; - private static final String SCHEME_TEL = "tel:"; // 电话号码URL前缀 - private static final String SCHEME_HTTP = "http:"; // 网络链接URL前缀 - private static final String SCHEME_EMAIL = "mailto:"; // 邮件链接URL前缀 + private static final String SCHEME_TEL = "tel:" ; + private static final String SCHEME_HTTP = "http:" ; + private static final String SCHEME_EMAIL = "mailto:" ; - // URL方案与对应的字符串资源ID的映射 private static final Map sSchemaActionResMap = new HashMap(); static { sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); @@ -54,30 +55,32 @@ public class NoteEditText extends EditText { } /** - * 由 {@link NoteEditActivity} 调用,用于删除或添加编辑文本 + * Call by the {@link NoteEditActivity} to delete or add edit text */ public interface OnTextViewChangeListener { /** - * 在 {@link KeyEvent#KEYCODE_DEL} 发生且文本为空时删除当前编辑文本 + * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens + * and the text is null */ void onEditTextDelete(int index, String text); /** - * 在 {@link KeyEvent#KEYCODE_ENTER} 发生时在当前编辑文本后添加新的编辑文本 + * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} + * happen */ void onEditTextEnter(int index, String text); /** - * 文本变化时隐藏或显示选项 + * Hide or show item option when text change */ void onTextChange(int index, boolean hasText); } - private OnTextViewChangeListener mOnTextViewChangeListener; // 文本变化监听器实例 + private OnTextViewChangeListener mOnTextViewChangeListener; public NoteEditText(Context context) { - super(context, null); // 调用父类构造函数 - mIndex = 0; // 初始化文本框索引为0 + super(context, null); + mIndex = 0; } // 设置当前文本框的索引 @@ -91,11 +94,11 @@ public class NoteEditText extends EditText { } public NoteEditText(Context context, AttributeSet attrs) { - super(context, attrs, android.R.attr.editTextStyle); // 调用父类构造函数并设置默认样式 + super(context, attrs, android.R.attr.editTextStyle); } public NoteEditText(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); // 调用父类构造函数并设置自定义样式 + super(context, attrs, defStyle); // TODO Auto-generated constructor stub } @@ -103,120 +106,120 @@ public class NoteEditText extends EditText { @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: // 触摸屏幕时 - int x = (int) event.getX(); // 获取触摸点的X坐标 - int y = (int) event.getY(); // 获取触摸点的Y坐标 - x -= getTotalPaddingLeft(); // 减去左内边距 - y -= getTotalPaddingTop(); // 减去上内边距 - x += getScrollX(); // 加上水平滚动位置 - y += getScrollY(); // 加上垂直滚动位置 - - Layout layout = getLayout(); // 获取文本布局信息 - int line = layout.getLineForVertical(y); // 根据Y坐标获取行号 - int off = layout.getOffsetForHorizontal(line, x); // 根据行号和X坐标获取偏移量 - Selection.setSelection(getText(), off); // 更新光标位置 + case MotionEvent.ACTION_DOWN: + + int x = (int) event.getX(); + int y = (int) event.getY(); + x -= getTotalPaddingLeft(); + y -= getTotalPaddingTop(); + x += getScrollX(); + y += getScrollY(); + + Layout layout = getLayout(); + int line = layout.getLineForVertical(y); + int off = layout.getOffsetForHorizontal(line, x); + Selection.setSelection(getText(), off); break; } - return super.onTouchEvent(event); // 调用父类的触摸事件处理方法 + return super.onTouchEvent(event); } // 处理按键按下事件,记录删除操作前的光标位置 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { - case KeyEvent.KEYCODE_ENTER: // 按下回车键 + case KeyEvent.KEYCODE_ENTER: if (mOnTextViewChangeListener != null) { - return false; // 如果设置了监听器,返回false以拦截按键事件 + return false; } break; - case KeyEvent.KEYCODE_DEL: // 按下删除键 - mSelectionStartBeforeDelete = getSelectionStart(); // 记录删除操作前的光标位置 + case KeyEvent.KEYCODE_DEL: + mSelectionStartBeforeDelete = getSelectionStart(); break; - default: // 其他按键 + default: break; } - return super.onKeyDown(keyCode, event); // 调用父类的按键按下事件处理方法 + return super.onKeyDown(keyCode, event); } // 处理按键弹起事件,根据按键类型执行相应操作 @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_DEL: // 弹起删除键 + switch(keyCode) { + case KeyEvent.KEYCODE_DEL: if (mOnTextViewChangeListener != null) { - if (0 == mSelectionStartBeforeDelete && mIndex != 0) { // 如果光标在文本开头且不是第一个文本框 - mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); // 通知监听器删除文本框 - return true; // 拦截按键事件 + if (0 == mSelectionStartBeforeDelete && mIndex != 0) { + mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); + return true; } } else { - Log.d(TAG, "OnTextViewChangeListener was not seted"); // 如果未设置监听器,记录日志 + Log.d(TAG, "OnTextViewChangeListener was not seted"); } break; - case KeyEvent.KEYCODE_ENTER: // 弹起回车键 + case KeyEvent.KEYCODE_ENTER: if (mOnTextViewChangeListener != null) { - int selectionStart = getSelectionStart(); // 获取光标位置 - String text = getText().subSequence(selectionStart, length()).toString(); // 获取光标后的文本 - setText(getText().subSequence(0, selectionStart)); // 将光标后的文本清空 - mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); // 通知监听器添加新的文本框 + int selectionStart = getSelectionStart(); + String text = getText().subSequence(selectionStart, length()).toString(); + setText(getText().subSequence(0, selectionStart)); + mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); } else { - Log.d(TAG, "OnTextViewChangeListener was not seted"); // 如果未设置监听器,记录日志 + Log.d(TAG, "OnTextViewChangeListener was not seted"); } break; - default: // 其他按键 + default: break; } - return super.onKeyUp(keyCode, event); // 调用父类的按键弹起事件处理方法 + return super.onKeyUp(keyCode, event); } // 当EditText焦点发生变化时调用,通知监听器文本是否有内容 @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { if (mOnTextViewChangeListener != null) { - if (!focused && TextUtils.isEmpty(getText())) { // 如果失去焦点且文本为空 - mOnTextViewChangeListener.onTextChange(mIndex, false); // 通知监听器文本内容为空 + if (!focused && TextUtils.isEmpty(getText())) { + mOnTextViewChangeListener.onTextChange(mIndex, false); } else { - mOnTextViewChangeListener.onTextChange(mIndex, true); // 通知监听器文本内容不为空 + mOnTextViewChangeListener.onTextChange(mIndex, true); } } - super.onFocusChanged(focused, direction, previouslyFocusedRect); // 调用父类的焦点变化处理方法 + super.onFocusChanged(focused, direction, previouslyFocusedRect); } // 创建上下文菜单,处理URL点击事件 @Override protected void onCreateContextMenu(ContextMenu menu) { - if (getText() instanceof Spanned) { // 如果文本是Spanned类型 - int selStart = getSelectionStart(); // 获取选择的起始位置 - int selEnd = getSelectionEnd(); // 获取选择的结束位置 + if (getText() instanceof Spanned) { + int selStart = getSelectionStart(); + int selEnd = getSelectionEnd(); - int min = Math.min(selStart, selEnd); // 计算选择的最小位置 - int max = Math.max(selStart, selEnd); // 计算选择的最大位置 + int min = Math.min(selStart, selEnd); + int max = Math.max(selStart, selEnd); - final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); // 获取选择区域内的URLSpan - if (urls.length == 1) { // 如果只有一个URLSpan + final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); + if (urls.length == 1) { int defaultResId = 0; - for (String schema : sSchemaActionResMap.keySet()) { - if (urls[0].getURL().indexOf(schema) >= 0) { // 根据URL前缀匹配对应的资源ID + for(String schema: sSchemaActionResMap.keySet()) { + if(urls[0].getURL().indexOf(schema) >= 0) { defaultResId = sSchemaActionResMap.get(schema); break; } } - if (defaultResId == 0) { // 如果没有匹配到前缀 - defaultResId = R.string.note_link_other; // 使用默认的资源ID + if (defaultResId == 0) { + defaultResId = R.string.note_link_other; } - // 添加上下文菜单项并设置点击监听器 menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { - // 点击菜单项时,触发URLSpan的点击事件 + // goto a new intent urls[0].onClick(NoteEditText.this); - return true; // 拦截点击事件 + return true; } }); } } - super.onCreateContextMenu(menu); // 调用父类的创建上下文菜单方法 + super.onCreateContextMenu(menu); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NoteItemData.java b/Notes-master/src/net/micode/notes/ui/NoteItemData.java index cde2ecd..632fe29 100644 --- a/Notes-master/src/net/micode/notes/ui/NoteItemData.java +++ b/Notes-master/src/net/micode/notes/ui/NoteItemData.java @@ -7,10 +7,11 @@ * * 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; @@ -26,23 +27,22 @@ import net.micode.notes.tool.DataUtils; // 该类用于从数据库游标中提取笔记项数据,并处理与笔记位置相关的逻辑 public class NoteItemData { - // 定义了查询数据库时要获取的列 static final String [] PROJECTION = new String [] { - NoteColumns.ID, // 笔记项的唯一标识ID - NoteColumns.ALERTED_DATE, // 笔记项的提醒日期 - NoteColumns.BG_COLOR_ID, // 笔记项的背景颜色ID - NoteColumns.CREATED_DATE, // 笔记项的创建日期 - NoteColumns.HAS_ATTACHMENT, // 笔记项是否有附件 - NoteColumns.MODIFIED_DATE, // 笔记项的修改日期 - NoteColumns.NOTES_COUNT, // 笔记项包含的笔记数量 - NoteColumns.PARENT_ID, // 笔记项的父ID,如果是文件夹下的笔记,则是文件夹ID - NoteColumns.SNIPPET, // 笔记项的摘要信息 - NoteColumns.TYPE, // 笔记项的类型,例如笔记、文件夹等 - NoteColumns.WIDGET_ID, // 与笔记项关联的小部件ID - NoteColumns.WIDGET_TYPE, // 小部件的类型 + NoteColumns.ID, + NoteColumns.ALERTED_DATE, + NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, + NoteColumns.HAS_ATTACHMENT, + NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, + NoteColumns.PARENT_ID, + NoteColumns.SNIPPET, + NoteColumns.TYPE, + NoteColumns.WIDGET_ID, + NoteColumns.WIDGET_TYPE, }; - // 定义了游标中各个列的索引位置,便于后续从游标中获取数据时使用 + // 定义了游标中各个列的索引位置 private static final int ID_COLUMN = 0; private static final int ALERTED_DATE_COLUMN = 1; private static final int BG_COLOR_ID_COLUMN = 2; @@ -57,84 +57,83 @@ public class NoteItemData { private static final int WIDGET_TYPE_COLUMN = 11; // 笔记项的各种属性 - private long mId; // 笔记项的唯一标识ID - private long mAlertDate; // 笔记项的提醒日期 - private int mBgColorId; // 笔记项的背景颜色ID - private long mCreatedDate; // 笔记项的创建日期 - private boolean mHasAttachment; // 笔记项是否有附件 - private long mModifiedDate; // 笔记项的修改日期 - private int mNotesCount; // 笔记项包含的笔记数量 - private long mParentId; // 笔记项的父ID,如果是文件夹下的笔记,则是文件夹ID - private String mSnippet; // 笔记项的摘要信息 - private int mType; // 笔记项的类型,例如笔记、文件夹等 - private int mWidgetId; // 与笔记项关联的小部件ID - private int mWidgetType; // 小部件的类型 - private String mName; // 笔记项关联的联系人名称 - private String mPhoneNumber; // 笔记项关联的联系人电话号码 + private long mId; + private long mAlertDate; + private int mBgColorId; + private long mCreatedDate; + private boolean mHasAttachment; + private long mModifiedDate; + private int mNotesCount; + private long mParentId; + private String mSnippet; + private int mType; + private int mWidgetId; + private int mWidgetType; + private String mName; + private String mPhoneNumber; // 笔记项在列表中的位置信息 - private boolean mIsLastItem; // 是否是列表中的最后一个项 - private boolean mIsFirstItem; // 是否是列表中的第一个项 - private boolean mIsOnlyOneItem; // 是否是列表中唯一的项 - private boolean mIsOneNoteFollowingFolder; // 是否是单个笔记跟在一个文件夹后 - private boolean mIsMultiNotesFollowingFolder; // 是否是多个笔记跟在一个文件夹后 + private boolean mIsLastItem; + private boolean mIsFirstItem; + private boolean mIsOnlyOneItem; + private boolean mIsOneNoteFollowingFolder; + private boolean mIsMultiNotesFollowingFolder; // 构造函数,从游标中提取笔记项数据 public NoteItemData(Context context, Cursor cursor) { - mId = cursor.getLong(ID_COLUMN); // 获取笔记项的ID - mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); // 获取笔记项的提醒日期 - mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN); // 获取笔记项的背景颜色ID - mCreatedDate = cursor.getLong(CREATED_DATE_COLUMN); // 获取笔记项的创建日期 - mHasAttachment = (cursor.getInt(HAS_ATTACHMENT_COLUMN) > 0) ? true : false; // 判断笔记项是否有附件 - mModifiedDate = cursor.getLong(MODIFIED_DATE_COLUMN); // 获取笔记项的修改日期 - mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN); // 获取笔记项包含的笔记数量 - mParentId = cursor.getLong(PARENT_ID_COLUMN); // 获取笔记项的父ID - mSnippet = cursor.getString(SNIPPET_COLUMN); // 获取笔记项的摘要信息 - mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED, "").replace(NoteEditActivity.TAG_UNCHECKED, ""); // 清理摘要中的特定标签 - mType = cursor.getInt(TYPE_COLUMN); // 获取笔记项的类型 - mWidgetId = cursor.getInt(WIDGET_ID_COLUMN); // 获取笔记项的小部件ID - mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); // 获取笔记项的小部件类型 - - mPhoneNumber = ""; // 初始化电话号码为空字符串 - if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { // 如果笔记项的父ID是呼叫记录文件夹的ID - mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId); // 通过笔记ID获取对应的呼叫记录的电话号码 - if (!TextUtils.isEmpty(mPhoneNumber)) { // 如果电话号码不为空 - mName = Contact.getContact(context, mPhoneNumber); // 通过电话号码查询联系人信息 - if (mName == null) { // 如果没有找到对应的联系人名称 - mName = mPhoneNumber; // 则将电话号码作为名称 + mId = cursor.getLong(ID_COLUMN); + mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); + mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN); + mCreatedDate = cursor.getLong(CREATED_DATE_COLUMN); + mHasAttachment = (cursor.getInt(HAS_ATTACHMENT_COLUMN) > 0) ? true : false; + mModifiedDate = cursor.getLong(MODIFIED_DATE_COLUMN); + mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN); + mParentId = cursor.getLong(PARENT_ID_COLUMN); + mSnippet = cursor.getString(SNIPPET_COLUMN); + mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED, "").replace( + NoteEditActivity.TAG_UNCHECKED, ""); + mType = cursor.getInt(TYPE_COLUMN); + mWidgetId = cursor.getInt(WIDGET_ID_COLUMN); + mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); + + mPhoneNumber = ""; + if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { + mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId); + if (!TextUtils.isEmpty(mPhoneNumber)) { + mName = Contact.getContact(context, mPhoneNumber); + if (mName == null) { + mName = mPhoneNumber; } } } - if (mName == null) { // 如果联系人名称依然为null - mName = ""; // 初始化为空字符串 + if (mName == null) { + mName = ""; } - checkPostion(cursor); // 检查笔记项在列表中的位置信息 + checkPostion(cursor); } // 检查笔记项在列表中的位置信息 private void checkPostion(Cursor cursor) { - mIsLastItem = cursor.isLast() ? true : false; // 设置是否是列表中的最后一个项 - mIsFirstItem = cursor.isFirst() ? true : false; // 设置是否是列表中的第一个项 - mIsOnlyOneItem = (cursor.getCount() == 1); // 如果列表中的项数为1,则设置为唯一项 - mIsMultiNotesFollowingFolder = false; // 初始化是否是多个笔记跟在一个文件夹后为false - mIsOneNoteFollowingFolder = false; // 初始化是否是单个笔记跟在一个文件夹后为false + mIsLastItem = cursor.isLast() ? true : false; + mIsFirstItem = cursor.isFirst() ? true : false; + mIsOnlyOneItem = (cursor.getCount() == 1); + mIsMultiNotesFollowingFolder = false; + mIsOneNoteFollowingFolder = false; - // 如果笔记项类型是笔记且不是列表中的第一个项 if (mType == Notes.TYPE_NOTE && !mIsFirstItem) { - int position = cursor.getPosition(); // 获取当前笔记项的位置 - if (cursor.moveToPrevious()) { // 将游标移动到前一行 - // 如果前一行的类型是文件夹或系统类型 - if (cursor.getInt(TYPE_COLUMN) == Notes.TYPE_FOLDER || cursor.getInt(TYPE_COLUMN) == Notes.TYPE_SYSTEM) { - // 如果列表中的项数大于当前位置加1 + int position = cursor.getPosition(); + if (cursor.moveToPrevious()) { + if (cursor.getInt(TYPE_COLUMN) == Notes.TYPE_FOLDER + || cursor.getInt(TYPE_COLUMN) == Notes.TYPE_SYSTEM) { if (cursor.getCount() > (position + 1)) { - mIsMultiNotesFollowingFolder = true; // 设置为多个笔记跟在一个文件夹后 + mIsMultiNotesFollowingFolder = true; } else { - mIsOneNoteFollowingFolder = true; // 设置为单个笔记跟在一个文件夹后 + mIsOneNoteFollowingFolder = true; } } - if (!cursor.moveToNext()) { // 将游标移动回原来的位置 - throw new IllegalStateException("cursor move to previous but can't move back"); // 如果移动失败,抛出异常 + if (!cursor.moveToNext()) { + throw new IllegalStateException("cursor move to previous but can't move back"); } } } @@ -142,112 +141,111 @@ public class NoteItemData { // 判断该笔记项是否是单个笔记跟在一个文件夹后 public boolean isOneFollowingFolder() { - return mIsOneNoteFollowingFolder; // 返回是否是单个笔记跟在一个文件夹后的结果 + return mIsOneNoteFollowingFolder; } // 判断该笔记项是否是多个笔记跟在一个文件夹后 public boolean isMultiFollowingFolder() { - return mIsMultiNotesFollowingFolder; // 返回是否是多个笔记跟在一个文件夹后的结果 + return mIsMultiNotesFollowingFolder; } // 判断该笔记项是否是列表中的最后一个项 public boolean isLast() { - return mIsLastItem; // 返回是否是列表中最后一个项的结果 + return mIsLastItem; } // 获取与该笔记项关联的呼叫记录的联系人名称 public String getCallName() { - return mName; // 返回关联的联系人名称 + return mName; } // 判断该笔记项是否是列表中的第一个项 public boolean isFirst() { - return mIsFirstItem; // 返回是否是列表中第一个项的结果 + return mIsFirstItem; } // 判断该笔记项是否是列表中唯一的项 public boolean isSingle() { - return mIsOnlyOneItem; // 返回是否是列表中唯一项的结果 + return mIsOnlyOneItem; } // 获取笔记项的ID public long getId() { - return mId; // 返回笔记项的ID + return mId; } // 获取笔记项的提醒日期 public long getAlertDate() { - return mAlertDate; // 返回笔记项的提醒日期 + return mAlertDate; } // 获取笔记项的创建日期 public long getCreatedDate() { - return mCreatedDate; // 返回笔记项的创建日期 + return mCreatedDate; } // 判断该笔记项是否有附件 public boolean hasAttachment() { - return mHasAttachment; // 返回笔记项是否有附件的结果 + return mHasAttachment; } // 获取笔记项的修改日期 public long getModifiedDate() { - return mModifiedDate; // 返回笔记项的修改日期 + return mModifiedDate; } // 获取笔记项的背景颜色ID public int getBgColorId() { - return mBgColorId; // 返回笔记项的背景颜色ID + return mBgColorId; } // 获取笔记项的父ID public long getParentId() { - return mParentId; // 返回笔记项的父ID + return mParentId; } // 获取笔记项包含的笔记数量 public int getNotesCount() { - return mNotesCount; // 返回笔记项包含的笔记数量 + return mNotesCount; } // 获取笔记项所在的文件夹ID public long getFolderId () { - return mParentId; // 返回笔记项所在的文件夹ID,与getParentId相同 + return mParentId; } // 获取笔记项的类型 public int getType() { - return mType; // 返回笔记项的类型 + return mType; } // 获取笔记项的小部件类型 public int getWidgetType() { - return mWidgetType; // 返回笔记项的小部件类型 + return mWidgetType; } // 获取笔记项的小部件ID public int getWidgetId() { - return mWidgetId; // 返回笔记项的小部件ID + return mWidgetId; } // 获取笔记项的摘要 public String getSnippet() { - return mSnippet; // 返回笔记项的摘要 + return mSnippet; } // 判断该笔记项是否有提醒 public boolean hasAlert() { - return (mAlertDate > 0); // 如果提醒日期大于0,表示有提醒 + return (mAlertDate > 0); } // 判断该笔记项是否是呼叫记录类型 public boolean isCallRecord() { - // 如果父ID是呼叫记录文件夹的ID且电话号码不为空,则是呼叫记录类型 return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber)); } // 静态方法,从游标中获取笔记项的类型 public static int getNoteType(Cursor cursor) { - return cursor.getInt(TYPE_COLUMN); // 从游标中获取笔记项的类型 + return cursor.getInt(TYPE_COLUMN); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/Notes-master/src/net/micode/notes/ui/NotesListActivity.java index e54f4a3..5893567 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesListActivity.java +++ b/Notes-master/src/net/micode/notes/ui/NotesListActivity.java @@ -1,3 +1,19 @@ +/* + * 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 + * + * 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; import android.app.Activity; @@ -62,104 +78,98 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashSet; -/** - * 笔记列表展示Activity,主要用于展示用户的笔记列表,新建笔记,批量删除笔记等操作 - */ public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { - // 定义了用于查询笔记列表和文件夹列表的token private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; + private static final int FOLDER_LIST_QUERY_TOKEN = 1; - // 定义了文件夹操作菜单项的id 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"; - // 枚举类,定义了当前Activity的不同状态 private enum ListEditState { NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER }; - private ListEditState mState; // 当前Activity状态 + private ListEditState mState; - private BackgroundQueryHandler mBackgroundQueryHandler; // 异步查询处理器 - private NotesListAdapter mNotesListAdapter; // 笔记列表适配器,负责展示笔记列表 - private ListView mNotesListView; // 笔记列表视图 - private Button mAddNewNote; // 新建笔记按钮 - private boolean mDispatch; // 是否需要将触摸事件分发给ListView - private int mOriginY; // 触摸开始时的Y坐标 - private int mDispatchY; // 触摸事件需要被分发时的Y坐标 - private TextView mTitleBar; // 标题栏文本视图 - private long mCurrentFolderId; // 当前显示的文件夹ID - private ContentResolver mContentResolver; // 内容解析器,用于操作数据库 - private ModeCallback mModeCallBack; // ActionMode回调,用于处理批量操作菜单 + private BackgroundQueryHandler mBackgroundQueryHandler; - private static final String TAG = "NotesListActivity"; // 日志标签 + private NotesListAdapter mNotesListAdapter; - public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; // 笔记列表滚动速率 + private ListView mNotesListView; - private NoteItemData mFocusNoteDataItem; // 当前选中的笔记项数据 + private Button mAddNewNote; - // 查询笔记列表时使用的SQL选择语句 - private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; + 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"; - // 查询根文件夹下的笔记列表时使用的SQL选择语句 + 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)"; - - // 打开或新建节点后的请求码 + 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(); } - /** - * 处理Activity返回的结果,如果是新建或打开笔记后的返回结果,则更新笔记列表 - * @param requestCode 请求码 - * @param resultCode 返回结果码 - * @param data 返回的Intent数据 - */ @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); } } - /** - * 从raw资源文件中读取应用介绍,并保存到本地数据库 - */ private void setAppInfoFromRawRes() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); // 获取偏好设置 - if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { // 如果尚未添加介绍 + 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); // 打开raw资源文件 + in = getResources().openRawResource(R.raw.introduction); if (in != null) { InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); char [] buf = new char[1024]; int len = 0; - while ((len = br.read(buf)) > 0) { // 读取文件内容 + while ((len = br.read(buf)) > 0) { sb.append(buf, 0, len); } } else { @@ -172,8 +182,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } finally { if(in != null) { try { - in.close(); // 关闭输入流 + in.close(); } catch (IOException e) { + // TODO Auto-generated catch block e.printStackTrace(); } } @@ -183,8 +194,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt 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(); // 更新偏好设置 + if (note.saveNote()) { + sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit(); } else { Log.e(TAG, "Save introduction note error"); return; @@ -195,71 +206,52 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override protected void onStart() { super.onStart(); - startAsyncNotesListQuery(); // 异步查询笔记列表并展示 + startAsyncNotesListQuery(); } - /** - * 初始化资源,主要包括: - * 1. 获取ContentResolver - * 2. 初始化BackgroundQueryHandler - * 3. 设置当前文件夹ID为根文件夹ID - * 4. 查找视图控件并设置监听器 - * 5. 初始化NotesListAdapter并绑定到ListView - * 6. 设置Activity状态为NOTE_LIST - */ private void initResources() { 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); // 设置长按监听器 + null, false); + mNotesListView.setOnItemClickListener(new OnListItemClickListener()); + mNotesListView.setOnItemLongClickListener(this); mNotesListAdapter = new NotesListAdapter(this); - mNotesListView.setAdapter(mNotesListAdapter); // 设置适配器 + mNotesListView.setAdapter(mNotesListAdapter); mAddNewNote = (Button) findViewById(R.id.btn_new_note); - mAddNewNote.setOnClickListener(this); // 设置点击监听器 - mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); // 设置触摸监听器 + 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(); // 初始化ActionMode回调 + mModeCallBack = new ModeCallback(); } - /** - * ActionMode回调类,用于处理批量操作菜单的创建、显示和点击事件 - */ private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener { - private DropdownMenu mDropDownMenu; // 下拉菜单 - private ActionMode mActionMode; // ActionMode - private MenuItem mMoveMenu; // 移动笔记的菜单项 + private DropdownMenu mDropDownMenu; + private ActionMode mActionMode; + private MenuItem mMoveMenu; - /** - * 创建ActionMode并设置菜单 - * @param mode ActionMode对象 - * @param menu 菜单对象 - * @return 返回true,表示ActionMode创建成功 - */ public boolean onCreateActionMode(ActionMode mode, Menu menu) { - getMenuInflater().inflate(R.menu.note_list_options, menu); // 设置菜单 - menu.findItem(R.id.delete).setOnMenuItemClickListener(this); // 设置删除菜单项的点击监听器 + 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); // 如果当前文件夹为通话记录文件夹或无用户文件夹,隐藏移动菜单项 + mMoveMenu.setVisible(false); } else { - mMoveMenu.setVisible(true); // 显示移动菜单项 - mMoveMenu.setOnMenuItemClickListener(this); // 设置移动菜单项的点击监听器 + mMoveMenu.setVisible(true); + mMoveMenu.setOnMenuItemClickListener(this); } mActionMode = mode; - mNotesListAdapter.setChoiceMode(true); // 设置列表适配器为选择模式 - mNotesListView.setLongClickable(false); // 禁用长按操作 - mAddNewNote.setVisibility(View.GONE); // 隐藏新建笔记按钮 + mNotesListAdapter.setChoiceMode(true); + mNotesListView.setLongClickable(false); + mAddNewNote.setVisibility(View.GONE); - // 设置自定义ActionMode视图 View customView = LayoutInflater.from(NotesListActivity.this).inflate( R.layout.note_list_dropdown_menu, null); mode.setCustomView(customView); @@ -268,112 +260,62 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt 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(); // 获取选中的笔记数量 - // 更新下拉菜单标题 + int selectedCount = mNotesListAdapter.getSelectedCount(); + // Update dropdown menu 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()) { // 如果所有笔记都被选中 + 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) { - // 不需要在ActionMode准备时修改菜单,返回false - return false; - } - - /** - * 处理菜单项点击事件 - * @param mode ActionMode对象 - * @param menu 菜单对象 - * @param item 被点击的菜单项 - * @param rangeStart 被点击的菜单项的起始位置(未使用) - * @param rangeEnd 被点击的菜单项的结束位置(未使用) - * @return 返回true,表示菜单项点击事件处理成功 - */ - public boolean onCreateActionMode(ActionMode mode, Menu menu, int rangeStart, int rangeEnd) { - // 不需要支持多选范围,返回false - return false; - } - - /** - * 处理菜单项点击事件 - * @param mode ActionMode对象 - * @param menu 菜单对象 - * @return 返回true,表示菜单项点击事件处理成功 - */ - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - // 不需要在ActionMode准备时修改菜单,返回false + // TODO Auto-generated method stub return false; } - /** - * 处理菜单项点击事件 - * @param mode ActionMode对象 - * @param item 被点击的菜单项 - * @return 返回true,表示菜单项点击事件处理成功 - */ public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - // 由onMenuItemClick方法处理点击事件 - return onMenuItemClick(item); + // TODO Auto-generated method stub + return false; } - /** - * 结束ActionMode - */ 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); } - /** - * 结束ActionMode - */ public void finishActionMode() { - mActionMode.finish(); // 结束ActionMode + mActionMode.finish(); } - /** - * 处理单个笔记项被选中或取消选中的事件 - * @param mode ActionMode对象 - * @param position 笔记项的位置 - * @param id 笔记项的ID - * @param checked 是否被选中 - */ - 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(); } - /** - * 处理菜单项点击事件 - * @param item 被点击的菜单项 - * @return 返回true,表示菜单项点击事件处理成功 - */ public boolean onMenuItemClick(MenuItem item) { - if (mNotesListAdapter.getSelectedCount() == 0) { // 如果没有选中的笔记 + if (mNotesListAdapter.getSelectedCount() == 0) { Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none), - Toast.LENGTH_SHORT).show(); // 显示提示信息 + Toast.LENGTH_SHORT).show(); return true; } @@ -388,14 +330,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - batchDelete(); // 批量删除笔记 + batchDelete(); } }); builder.setNegativeButton(android.R.string.cancel, null); - builder.show(); // 显示确认对话框 + builder.show(); break; case R.id.move: - startQueryDestinationFolders(); // 查询目标文件夹 + startQueryDestinationFolders(); break; default: return false; @@ -404,10 +346,8 @@ 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: { @@ -415,90 +355,82 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt int screenHeight = display.getHeight(); int newNoteViewHeight = mAddNewNote.getHeight(); int start = screenHeight - newNoteViewHeight; + int eventY = start + (int) event.getY(); /** - * 减去标题栏的高度,以便准确计算触摸位置 + * Minus TitleBar's height */ if (mState == ListEditState.SUB_FOLDER) { eventY -= mTitleBar.getHeight(); start -= mTitleBar.getHeight(); } /** - * 处理按钮透明部分的触摸事件,将触摸事件分发给底层的ListView - * 透明部分的公式:y=-0.12x+94(单位:像素),基于按钮左边缘的坐标系 - * 94表示透明部分的最大高度 - * 注意:如果按钮背景发生变化,此公式需要相应调整 + * 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. */ if (event.getY() < (event.getX() * (-0.12) + 94)) { - // 获取ListView最后一个可见项 View view = mNotesListView.getChildAt(mNotesListView.getChildCount() - 1 - mNotesListView.getFooterViewsCount()); if (view != null && view.getBottom() > start && (view.getTop() < (start + 94))) { mOriginY = (int) event.getY(); mDispatchY = eventY; - event.setLocation(event.getX(), mDispatchY); // 设置新的触摸位置 + event.setLocation(event.getX(), mDispatchY); mDispatch = true; - return mNotesListView.dispatchTouchEvent(event); // 分发触摸事件 + return mNotesListView.dispatchTouchEvent(event); } } break; } case MotionEvent.ACTION_MOVE: { if (mDispatch) { - mDispatchY += (int) event.getY() - mOriginY; // 更新触摸位置 - event.setLocation(event.getX(), mDispatchY); // 设置新的触摸位置 - return mNotesListView.dispatchTouchEvent(event); // 分发触摸事件 + mDispatchY += (int) event.getY() - mOriginY; + event.setLocation(event.getX(), mDispatchY); + return mNotesListView.dispatchTouchEvent(event); } break; } default: { if (mDispatch) { - event.setLocation(event.getX(), mDispatchY); // 设置新的触摸位置 + event.setLocation(event.getX(), mDispatchY); mDispatch = false; - return mNotesListView.dispatchTouchEvent(event); // 分发触摸事件 + return mNotesListView.dispatchTouchEvent(event); } break; } } return false; } + }; - /** - * 异步查询笔记列表 - */ private void startAsyncNotesListQuery() { 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"); // 执行异步查询 + }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); } - /** - * BackgroundQueryHandler,用于处理异步查询结果 - */ private final class BackgroundQueryHandler extends AsyncQueryHandler { public BackgroundQueryHandler(ContentResolver contentResolver) { super(contentResolver); } - /** - * 处理查询完成后的结果 - * @param token 查询token - * @param cookie 传递给查询的额外信息(未使用) - * @param cursor 查询结果的游标 - */ @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { switch (token) { case FOLDER_NOTE_LIST_QUERY_TOKEN: - mNotesListAdapter.changeCursor(cursor); // 更新笔记列表适配器的游标 + mNotesListAdapter.changeCursor(cursor); break; case FOLDER_LIST_QUERY_TOKEN: if (cursor != null && cursor.getCount() > 0) { - showFolderListMenu(cursor); // 显示文件夹列表菜单 + showFolderListMenu(cursor); } else { Log.e(TAG, "Query folder failed"); } @@ -509,16 +441,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } - /** - * 显示文件夹列表菜单 - * @param cursor 查询结果的游标 - */ 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.setAdapter(adapter, new DialogInterface.OnClickListener() { - // 处理菜单项点击事件 + public void onClick(DialogInterface dialog, int which) { DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which)); @@ -527,39 +455,34 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt getString(R.string.format_move_notes_to_folder, mNotesListAdapter.getSelectedCount(), adapter.getFolderName(NotesListActivity.this, which)), - Toast.LENGTH_SHORT).show(); // 显示提示信息 - mModeCallBack.finishActionMode(); // 结束ActionMode + Toast.LENGTH_SHORT).show(); + 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); // 启动NoteEditActivity并等待返回结果 + this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); } - /** - * 批量删除笔记 - */ private void batchDelete() { new AsyncTask>() { protected HashSet doInBackground(Void... unused) { - HashSet widgets = mNotesListAdapter.getSelectedWidget(); // 获取选中的笔记关联的Widget属性 + 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"); @@ -574,19 +497,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt for (AppWidgetAttribute widget : widgets) { if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { - updateWidget(widget.widgetId, widget.widgetType); // 更新Widget + updateWidget(widget.widgetId, widget.widgetType); } } } - mModeCallBack.finishActionMode(); // 结束ActionMode + mModeCallBack.finishActionMode(); } - }.execute(); // 执行异步任务 + }.execute(); } - /** - * 删除文件夹 - * @param folderId 文件夹ID - */ private void deleteFolder(long folderId) { if (folderId == Notes.ID_ROOT_FOLDER) { Log.e(TAG, "Wrong folder id, should not happen " + folderId); @@ -596,214 +515,185 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt HashSet ids = new HashSet(); ids.add(folderId); HashSet widgets = DataUtils.getFolderNoteWidget(mContentResolver, - folderId); // 获取文件夹关联的Widget属性 + 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) { - updateWidget(widget.widgetId, widget.widgetType); // 更新Widget + updateWidget(widget.widgetId, widget.widgetType); } } } } - /** - * 打开笔记节点 - * @param data 笔记数据 - */ 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); // 启动NoteEditActivity并等待返回结果 + this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); } - /** - * 打开文件夹 - * @param data 文件夹数据 - */ private void openFolder(NoteItemData data) { - mCurrentFolderId = data.getId(); // 更新当前文件夹ID - startAsyncNotesListQuery(); // 异步查询笔记列表 + mCurrentFolderId = data.getId(); + 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); } - /** - * 处理View的点击事件 - * @param v 被点击的View - */ public void onClick(View v) { switch (v.getId()) { case R.id.btn_new_note: - createNewNote(); // 创建新笔记 + 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); } } - /** - * 隐藏软键盘 - * @param view 触发隐藏软键盘的View - */ 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 是否为创建文件夹 - */ 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(); // 显示软键盘 + showSoftInput(); if (!create) { if (mFocusNoteDataItem != null) { - etName.setText(mFocusNoteDataItem.getSnippet()); // 设置文件夹名称为当前选中的文件夹摘要 - builder.setTitle(getString(R.string.menu_folder_change_name)); // 设置对话框标题为修改文件夹名称 + etName.setText(mFocusNoteDataItem.getSnippet()); + 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.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 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); // 隐藏软键盘 + hideSoftInput(etName); String name = etName.getText().toString(); - if (DataUtils.checkVisibleFolderName(mContentResolver, name)) { // 检查文件夹名称是否已存在 + if (DataUtils.checkVisibleFolderName(mContentResolver, name)) { Toast.makeText(NotesListActivity.this, getString(R.string.folder_exist, name), - Toast.LENGTH_LONG).show(); // 显示提示信息 - etName.setSelection(0, etName.length()); // 选中文件夹名称文本 + Toast.LENGTH_LONG).show(); + 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()) - }); // 更新数据库中的文件夹信息 + }); } } 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); // 插入新的文件夹到数据库 + values.put(NoteColumns.SNIPPET, name); + values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + mContentResolver.insert(Notes.CONTENT_NOTE_URI, values); } - dialog.dismiss(); // 关闭对话框 + dialog.dismiss(); } }); if (TextUtils.isEmpty(etName.getText())) { - positive.setEnabled(false); // 如果文件夹名称为空,则禁用确定按钮 + 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 onTextChanged(CharSequence s, int start, int before, int count) { - if (TextUtils.isEmpty(s)) { - positive.setEnabled(false); // 如果文件夹名称为空,则禁用确定按钮 + if (TextUtils.isEmpty(etName.getText())) { + positive.setEnabled(false); } else { - positive.setEnabled(true); // 如果文件夹名称不为空,则启用确定按钮 + positive.setEnabled(true); } } public void afterTextChanged(Editable s) { - // 不需要处理文本改变后的事件 + // TODO Auto-generated method stub + } }); } - /** - * 处理返回键事件 - */ @Override public void onBackPressed() { switch (mState) { case SUB_FOLDER: - mCurrentFolderId = Notes.ID_ROOT_FOLDER; // 返回根文件夹 - mState = ListEditState.NOTE_LIST; // 设置为笔记列表状态 - startAsyncNotesListQuery(); // 异步查询笔记列表 - mTitleBar.setVisibility(View.GONE); // 隐藏标题栏 + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + startAsyncNotesListQuery(); + mTitleBar.setVisibility(View.GONE); break; case CALL_RECORD_FOLDER: - mCurrentFolderId = Notes.ID_ROOT_FOLDER; // 返回根文件夹 - mState = ListEditState.NOTE_LIST; // 设置为笔记列表状态 - mAddNewNote.setVisibility(View.VISIBLE); // 显示新建笔记按钮 - mTitleBar.setVisibility(View.GONE); // 隐藏标题栏 - startAsyncNotesListQuery(); // 异步查询笔记列表 + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + mAddNewNote.setVisibility(View.VISIBLE); + mTitleBar.setVisibility(View.GONE); + startAsyncNotesListQuery(); break; case NOTE_LIST: - super.onBackPressed(); // 调用父类的返回键处理方法 + super.onBackPressed(); break; default: break; } } - /** - * 更新Widget - * @param appWidgetId Widget的ID - * @param appWidgetType Widget的类型 - */ private void updateWidget(int appWidgetId, int appWidgetType) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); if (appWidgetType == Notes.TYPE_WIDGET_2X) { - intent.setClass(this, NoteWidgetProvider_2x.class); // 设置Widget更新的广播接收器 + intent.setClass(this, NoteWidgetProvider_2x.class); } else if (appWidgetType == Notes.TYPE_WIDGET_4X) { - intent.setClass(this, NoteWidgetProvider_4x.class); // 设置Widget更新的广播接收器 + intent.setClass(this, NoteWidgetProvider_4x.class); } else { Log.e(TAG, "Unspported widget type"); return; @@ -813,20 +703,17 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt appWidgetId }); - sendBroadcast(intent); // 发送广播通知Widget更新内容 + 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); // 添加修改文件夹名称选项 + 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); } } }; @@ -834,16 +721,11 @@ 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); } - /** - * 处理上下文菜单项点击事件 - * @param item 被点击的菜单项 - * @return 返回true,表示事件处理成功 - */ @Override public boolean onContextItemSelected(MenuItem item) { if (mFocusNoteDataItem == null) { @@ -852,7 +734,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } switch (item.getItemId()) { case MENU_FOLDER_VIEW: - openFolder(mFocusNoteDataItem); // 打开文件夹 + openFolder(mFocusNoteDataItem); break; case MENU_FOLDER_DELETE: AlertDialog.Builder builder = new AlertDialog.Builder(this); @@ -862,14 +744,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt 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(); // 显示确认对话框 + builder.show(); break; case MENU_FOLDER_CHANGE_NAME: - showCreateOrModifyFolderDialog(false); // 显示修改文件夹名称对话框 + showCreateOrModifyFolderDialog(false); break; default: break; @@ -878,67 +760,57 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } - /** - * 准备选项菜单 - * @param menu 菜单对象 - * @return 返回true,表示菜单准备成功 - */ @Override public boolean onPrepareOptionsMenu(Menu menu) { - menu.clear(); // 清空菜单 + menu.clear(); if (mState == ListEditState.NOTE_LIST) { - getMenuInflater().inflate(R.menu.note_list, menu); // 设置笔记列表菜单 - // 设置同步或取消同步菜单项标题 + getMenuInflater().inflate(R.menu.note_list, menu); + // set sync or sync_cancel 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); } return true; } - /** - * 处理选项菜单项点击事件 - * @param item 被点击的菜单项 - * @return 返回true,表示事件处理成功 - */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_new_folder: { - showCreateOrModifyFolderDialog(true); // 显示创建文件夹对话框 + showCreateOrModifyFolderDialog(true); break; } case R.id.menu_export_text: { - exportNoteToText(); // 导出笔记到文本文件 + exportNoteToText(); break; } case R.id.menu_sync: { if (isSyncMode()) { if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) { - GTaskSyncService.startSync(this); // 开始同步 + GTaskSyncService.startSync(this); } else { - GTaskSyncService.cancelSync(this); // 取消同步 + GTaskSyncService.cancelSync(this); } } else { - startPreferenceActivity(); // 启动偏好设置Activity + startPreferenceActivity(); } break; } case R.id.menu_setting: { - startPreferenceActivity(); // 启动偏好设置Activity + startPreferenceActivity(); break; } case R.id.menu_new_note: { - createNewNote(); // 创建新笔记 + createNewNote(); break; } case R.id.menu_search: - onSearchRequested(); // 处理搜索请求 + onSearchRequested(); break; default: break; @@ -946,25 +818,19 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } - /** - * 处理搜索请求 - * @return 返回true,表示搜索请求处理成功 - */ @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); new AsyncTask() { + @Override protected Integer doInBackground(Void... unused) { - return backup.exportToText(); // 执行导出操作 + return backup.exportToText(); } @Override @@ -972,63 +838,54 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt 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)); // 设置对话框标题为导出失败 + .getString(R.string.failed_sdcard_export)); builder.setMessage(NotesListActivity.this - .getString(R.string.error_sdcard_unmounted)); // 设置对话框消息为SD卡未挂载 + .getString(R.string.error_sdcard_unmounted)); builder.setPositiveButton(android.R.string.ok, null); - builder.show(); // 显示对话框 + builder.show(); } else if (result == BackupUtils.STATE_SUCCESS) { AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); builder.setTitle(NotesListActivity.this - .getString(R.string.success_sdcard_export)); // 设置对话框标题为导出成功 + .getString(R.string.success_sdcard_export)); builder.setMessage(NotesListActivity.this.getString( R.string.format_exported_file_location, backup .getExportedTextFileName(), backup.getExportedTextFileDir())); builder.setPositiveButton(android.R.string.ok, null); - builder.show(); // 显示对话框 + 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)); // 设置对话框标题为导出失败 + .getString(R.string.failed_sdcard_export)); builder.setMessage(NotesListActivity.this - .getString(R.string.error_sdcard_export)); // 设置对话框消息为系统错误 + .getString(R.string.error_sdcard_export)); builder.setPositiveButton(android.R.string.ok, null); - builder.show(); // 显示对话框 + builder.show(); } } - }.execute(); // 执行异步任务 + }.execute(); } - /** - * 判断是否处于同步模式 - * @return 返回true,表示处于同步模式;否则返回false - */ private boolean isSyncMode() { - return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; // 通过偏好设置判断是否设置了同步账户 + return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } - /** - * 启动偏好设置Activity - */ private void startPreferenceActivity() { Activity from = getParent() != null ? getParent() : this; Intent intent = new Intent(from, NotesPreferenceActivity.class); - from.startActivityIfNeeded(intent, -1); // 启动偏好设置Activity + 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; } @@ -1037,9 +894,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt case NOTE_LIST: if (item.getType() == Notes.TYPE_FOLDER || item.getType() == Notes.TYPE_SYSTEM) { - openFolder(item); // 打开文件夹 + openFolder(item); } else if (item.getType() == Notes.TYPE_NOTE) { - openNode(item); // 打开笔记 + openNode(item); } else { Log.e(TAG, "Wrong note type in NOTE_LIST"); } @@ -1047,7 +904,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt 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"); } @@ -1057,11 +914,9 @@ 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: @@ -1073,35 +928,27 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt FoldersListAdapter.PROJECTION, selection, new String[] { - String.valueOf(Notes.TYPE_FOLDER), // 文件夹类型 - String.valueOf(Notes.ID_TRASH_FOLER), // 废纸篓文件夹ID - String.valueOf(mCurrentFolderId) // 当前文件夹ID + String.valueOf(Notes.TYPE_FOLDER), + String.valueOf(Notes.ID_TRASH_FOLER), + String.valueOf(mCurrentFolderId) }, - NoteColumns.MODIFIED_DATE + " DESC"); // 按修改日期降序排序 + NoteColumns.MODIFIED_DATE + " DESC"); } - /** - * 处理笔记项长按事件 - * @param parent 父视图 - * @param view 被长按的视图 - * @param position 被长按的笔记项的位置 - * @param id 被长按的笔记项的ID - * @return 返回true,表示事件处理成功 - */ 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) { // 启动ActionMode - mModeCallBack.onItemCheckedStateChanged(null, position, id, true); // 选中笔记项 - mNotesListView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); // 提供长按反馈 + if (mNotesListView.startActionMode(mModeCallBack) != null) { + 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); // 设置上下文菜单监听器 + mNotesListView.setOnCreateContextMenuListener(mFolderOnCreateContextMenuListener); } } return false; } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java b/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java index 66148aa..fc77697 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java +++ b/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java @@ -1,193 +1,200 @@ /* - * 版权 (c) 2010-2011, MiCode开源社区 (www.micode.net) + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * - * 根据Apache许可证2.0版(“许可证”)授权; - * 除非适用法律要求或书面同意,软件按“现状”基础提供, - * 不附带任何明示或暗示的保证或条件。 - * 有关许可证下的权限和限制,请参阅许可证。 + * 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 + * + * 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; - + import android.content.Context; import android.database.Cursor; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.CursorAdapter; - + import net.micode.notes.data.Notes; - + import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; - + // 自定义的CursorAdapter,用于显示笔记列表 public class NotesListAdapter extends CursorAdapter { private static final String TAG = "NotesListAdapter"; - private Context mContext; // 上下文环境 - private HashMap mSelectedIndex; // 记录选中的笔记位置 - private int mNotesCount; // 笔记总数 - private boolean mChoiceMode; // 是否处于多选模式 - + private Context mContext; + private HashMap mSelectedIndex; + private int mNotesCount; + private boolean mChoiceMode; + // 用于存储小部件属性的内部类 public static class AppWidgetAttribute { - public int widgetId; // 小部件ID - public int widgetType; // 小部件类型 + public int widgetId; + public int widgetType; }; - + // 构造函数,初始化上下文和选择索引 public NotesListAdapter(Context context) { - super(context, null); // 调用父类构造函数,不立即绑定任何游标 - mSelectedIndex = new HashMap(); // 初始化选择索引 - mContext = context; // 初始化上下文 - mNotesCount = 0; // 初始化笔记数量为0 + super(context, null); + mSelectedIndex = new HashMap(); + mContext = context; + mNotesCount = 0; } - + // 创建新的视图项 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { - return new NotesListItem(context); // 创建一个新的NotesListItem视图 + return new NotesListItem(context); } - + // 绑定数据到视图项 @Override public void bindView(View view, Context context, Cursor cursor) { - if (view instanceof NotesListItem) { // 检查视图是否为NotesListItem类型 - NoteItemData itemData = new NoteItemData(context, cursor); // 创建NoteItemData对象,用于封装笔记数据 - ((NotesListItem) view).bind(context, itemData, mChoiceMode, // 调用NotesListItem的bind方法,绑定数据 - isSelectedItem(cursor.getPosition())); // 传递当前项是否被选中的信息 + if (view instanceof NotesListItem) { + NoteItemData itemData = new NoteItemData(context, cursor); + ((NotesListItem) view).bind(context, itemData, mChoiceMode, + isSelectedItem(cursor.getPosition())); } } - + // 设置指定位置的项是否被选中,并通知数据集发生变化 public void setCheckedItem(final int position, final boolean checked) { - mSelectedIndex.put(position, checked); // 更新选中状态 - notifyDataSetChanged(); // 通知数据集发生变化,刷新UI + mSelectedIndex.put(position, checked); + notifyDataSetChanged(); } - + // 检查当前是否处于多选模式 public boolean isInChoiceMode() { - return mChoiceMode; // 返回当前的多选模式状态 + return mChoiceMode; } - + // 设置多选模式,清空选择索引 public void setChoiceMode(boolean mode) { - mSelectedIndex.clear(); // 清空选择索引 - mChoiceMode = mode; // 更新多选模式状态 + mSelectedIndex.clear(); + mChoiceMode = mode; } - + // 全选或全不选所有笔记 public void selectAll(boolean checked) { - Cursor cursor = getCursor(); // 获取当前绑定的游标 - for (int i = 0; i < getCount(); i++) { // 遍历所有笔记 - if (cursor.moveToPosition(i)) { // 移动到指定位置 - if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) { // 检查是否为笔记类型 - setCheckedItem(i, checked); // 设置选中状态 + Cursor cursor = getCursor(); + for (int i = 0; i < getCount(); i++) { + if (cursor.moveToPosition(i)) { + if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) { + setCheckedItem(i, checked); } } } } - + // 获取所有选中的笔记ID集合 public HashSet getSelectedItemIds() { - HashSet itemSet = new HashSet(); // 初始化选中笔记ID集合 - for (Integer position : mSelectedIndex.keySet()) { // 遍历所有选中的位置 - if (mSelectedIndex.get(position) == true) { // 检查位置是否被选中 - Long id = getItemId(position); // 获取笔记ID - if (id == Notes.ID_ROOT_FOLDER) { // 检查是否为根文件夹ID(错误情况) - Log.d(TAG, "Wrong item id, should not happen"); // 记录日志 + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Long id = getItemId(position); + if (id == Notes.ID_ROOT_FOLDER) { + Log.d(TAG, "Wrong item id, should not happen"); } else { - itemSet.add(id); // 将笔记ID添加到集合 + itemSet.add(id); } } } - return itemSet; // 返回选中笔记ID集合 + + return itemSet; } - + // 获取所有选中的小部件属性集合 public HashSet getSelectedWidget() { - HashSet itemSet = new HashSet(); // 初始化选中小部件属性集合 - for (Integer position : mSelectedIndex.keySet()) { // 遍历所有选中的位置 - if (mSelectedIndex.get(position) == true) { // 检查位置是否被选中 - Cursor c = (Cursor) getItem(position); // 获取对应位置的游标 - if (c != null) { // 检查游标是否有效 - AppWidgetAttribute widget = new AppWidgetAttribute(); // 创建一个新的小部件属性对象 - NoteItemData item = new NoteItemData(mContext, c); // 创建NoteItemData对象,用于封装笔记数据 - widget.widgetId = item.getWidgetId(); // 设置小部件ID - widget.widgetType = item.getWidgetType(); // 设置小部件类型 - itemSet.add(widget); // 将小部件属性对象添加到集合 + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Cursor c = (Cursor) getItem(position); + if (c != null) { + AppWidgetAttribute widget = new AppWidgetAttribute(); + NoteItemData item = new NoteItemData(mContext, c); + widget.widgetId = item.getWidgetId(); + widget.widgetType = item.getWidgetType(); + itemSet.add(widget); /** * Don't close cursor here, only the adapter could close it - * 不要在这里关闭游标,只有适配器可以关闭游标 */ } else { - Log.e(TAG, "Invalid cursor"); // 记录无效游标日志 - return null; // 返回null + Log.e(TAG, "Invalid cursor"); + return null; } } } - return itemSet; // 返回选中小部件属性集合 + return itemSet; } - + // 获取选中的笔记数量 public int getSelectedCount() { - Collection values = mSelectedIndex.values(); // 获取所有选中状态值 + Collection values = mSelectedIndex.values(); if (null == values) { - return 0; // 如果选中状态值为空,返回0 + return 0; } - Iterator iter = values.iterator(); // 创建迭代器 - int count = 0; // 初始化计数器 + Iterator iter = values.iterator(); + int count = 0; while (iter.hasNext()) { - if (true == iter.next()) { // 检查是否为选中状态 - count++; // 计数器加一 + if (true == iter.next()) { + count++; } } - return count; // 返回选中的笔记数量 + return count; } - + // 检查是否所有笔记都被选中 public boolean isAllSelected() { - int checkedCount = getSelectedCount(); // 获取选中的笔记数量 - return (checkedCount != 0 && checkedCount == mNotesCount); // 检查选中的笔记数量是否等于笔记总数 + int checkedCount = getSelectedCount(); + return (checkedCount != 0 && checkedCount == mNotesCount); } - + // 检查指定位置的项是否被选中 public boolean isSelectedItem(final int position) { - if (null == mSelectedIndex.get(position)) { // 检查指定位置是否被选中 - return false; // 如果没有被选中,返回false + if (null == mSelectedIndex.get(position)) { + return false; } - return mSelectedIndex.get(position); // 返回选中状态 + return mSelectedIndex.get(position); } - + // 当数据内容发生变化时,更新笔记数量 @Override protected void onContentChanged() { - super.onContentChanged(); // 调用父类方法 - calcNotesCount(); // 计算笔记数量 + super.onContentChanged(); + calcNotesCount(); } - + // 更改Cursor时,更新笔记数量 @Override public void changeCursor(Cursor cursor) { - super.changeCursor(cursor); // 调用父类方法 - calcNotesCount(); // 计算笔记数量 + super.changeCursor(cursor); + calcNotesCount(); } - + // 计算笔记数量 private void calcNotesCount() { - mNotesCount = 0; // 初始化笔记数量为0 - for (int i = 0; i < getCount(); i++) { // 遍历所有笔记 - Cursor c = (Cursor) getItem(i); // 获取对应位置的游标 - if (c != null) { // 检查游标是否有效 - if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { // 检查是否为笔记类型 - mNotesCount++; // 计数器加一 + mNotesCount = 0; + for (int i = 0; i < getCount(); i++) { + Cursor c = (Cursor) getItem(i); + if (c != null) { + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { + mNotesCount++; } } else { - Log.e(TAG, "Invalid cursor"); // 记录无效游标日志 - return; // 返回 + Log.e(TAG, "Invalid cursor"); + return; } } } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesListItem.java b/Notes-master/src/net/micode/notes/ui/NotesListItem.java index 09f0ebd..1546bbe 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesListItem.java +++ b/Notes-master/src/net/micode/notes/ui/NotesListItem.java @@ -31,101 +31,80 @@ import net.micode.notes.tool.ResourceParser.NoteItemBgResources; // NotesListItem 类继承自 LinearLayout,用于表示笔记列表中的一个项 public class NotesListItem extends LinearLayout { - private ImageView mAlert; // 用于显示笔记的提醒图标 - private TextView mTitle; // 用于显示笔记的标题 - private TextView mTime; // 用于显示笔记的修改时间 - private TextView mCallName; // 用于显示与笔记相关的联系人姓名 - private NoteItemData mItemData; // 存储当前笔记项的数据 - private CheckBox mCheckBox; // 用于选择笔记项的复选框 + private ImageView mAlert; + private TextView mTitle; + private TextView mTime; + private TextView mCallName; + private NoteItemData mItemData; + private CheckBox mCheckBox; // 构造函数,初始化 NotesListItem 的视图组件 public NotesListItem(Context context) { super(context); - // 从资源文件中加载布局文件 R.layout.note_item 到当前 NotesListItem 中 inflate(context, R.layout.note_item, this); - // 查找布局文件中的 ImageView 组件,并赋值给 mAlert mAlert = (ImageView) findViewById(R.id.iv_alert_icon); - // 查找布局文件中的 TextView 组件,并赋值给 mTitle mTitle = (TextView) findViewById(R.id.tv_title); - // 查找布局文件中的 TextView 组件,并赋值给 mTime mTime = (TextView) findViewById(R.id.tv_time); - // 查找布局文件中的 TextView 组件,并赋值给 mCallName mCallName = (TextView) findViewById(R.id.tv_name); - // 查找布局文件中的 CheckBox 组件,并赋值给 mCheckBox mCheckBox = (CheckBox) findViewById(android.R.id.checkbox); } // 绑定数据到 NotesListItem 的视图组件,并设置选择模式和选中状态 public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) { - // 如果处于选择模式并且笔记项类型为普通笔记,则显示复选框 if (choiceMode && data.getType() == Notes.TYPE_NOTE) { mCheckBox.setVisibility(View.VISIBLE); - mCheckBox.setChecked(checked); // 设置复选框的选中状态 + mCheckBox.setChecked(checked); } else { - mCheckBox.setVisibility(View.GONE); // 否则隐藏复选框 + mCheckBox.setVisibility(View.GONE); } - mItemData = data; // 存储当前绑定的数据 - // 如果当前笔记项的 ID 是通话记录文件夹的 ID + mItemData = data; if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { - mCallName.setVisibility(View.GONE); // 隐藏联系人姓名 TextView - mAlert.setVisibility(View.VISIBLE); // 显示提醒图标 ImageView - mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); // 设置标题 TextView 的文本样式 - // 设置标题 TextView 的文本内容为通话记录文件夹名称及其中包含的笔记数量 + mCallName.setVisibility(View.GONE); + mAlert.setVisibility(View.VISIBLE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); mTitle.setText(context.getString(R.string.call_record_folder_name) + context.getString(R.string.format_folder_files_count, data.getNotesCount())); - mAlert.setImageResource(R.drawable.call_record); // 设置提醒图标 ImageView 的图片资源为通话记录图标 - } - // 如果当前笔记项的父目录 ID 是通话记录文件夹的 ID - else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) { - mCallName.setVisibility(View.VISIBLE); // 显示联系人姓名 TextView - mCallName.setText(data.getCallName()); // 设置联系人姓名 TextView 的文本内容 - mTitle.setTextAppearance(context, R.style.TextAppearanceSecondaryItem); // 设置标题 TextView 的文本样式 - // 设置标题 TextView 的文本内容为笔记内容的摘要 + mAlert.setImageResource(R.drawable.call_record); + } else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) { + mCallName.setVisibility(View.VISIBLE); + mCallName.setText(data.getCallName()); + mTitle.setTextAppearance(context,R.style.TextAppearanceSecondaryItem); mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); - // 如果笔记项有提醒,则显示提醒图标 ImageView if (data.hasAlert()) { - mAlert.setImageResource(R.drawable.clock); // 设置提醒图标 ImageView 的图片资源为时钟图标 + mAlert.setImageResource(R.drawable.clock); mAlert.setVisibility(View.VISIBLE); } else { - mAlert.setVisibility(View.GONE); // 否则隐藏提醒图标 ImageView + mAlert.setVisibility(View.GONE); } - } - // 如果当前笔记项既不是通话记录文件夹也不是其子项 - else { - mCallName.setVisibility(View.GONE); // 隐藏联系人姓名 TextView - mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); // 设置标题 TextView 的文本样式 + } else { + mCallName.setVisibility(View.GONE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); - // 如果笔记项类型为文件夹 if (data.getType() == Notes.TYPE_FOLDER) { - mTitle.setText(data.getSnippet() // 设置标题 TextView 的文本内容为文件夹名称 + mTitle.setText(data.getSnippet() + context.getString(R.string.format_folder_files_count, - data.getNotesCount())); // 并追加其中包含的笔记数量 - mAlert.setVisibility(View.GONE); // 隐藏提醒图标 ImageView + data.getNotesCount())); + mAlert.setVisibility(View.GONE); } else { - // 设置标题 TextView 的文本内容为笔记内容的摘要 mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); - // 如果笔记项有提醒,则显示提醒图标 ImageView if (data.hasAlert()) { - mAlert.setImageResource(R.drawable.clock); // 设置提醒图标 ImageView 的图片资源为时钟图标 + mAlert.setImageResource(R.drawable.clock); mAlert.setVisibility(View.VISIBLE); } else { - mAlert.setVisibility(View.GONE); // 否则隐藏提醒图标 ImageView + mAlert.setVisibility(View.GONE); } } } - // 设置时间 TextView 的文本内容为笔记的相对修改时间(如“3 小时前”) mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate())); - setBackground(data); // 根据笔记项的数据设置背景资源 + setBackground(data); } // 根据数据设置 NotesListItem 的背景资源 private void setBackground(NoteItemData data) { - int id = data.getBgColorId(); // 获取笔记项的背景颜色 ID - // 如果笔记项类型为普通笔记 + int id = data.getBgColorId(); if (data.getType() == Notes.TYPE_NOTE) { - // 根据笔记项的位置状态设置不同的背景资源 if (data.isSingle() || data.isOneFollowingFolder()) { setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id)); } else if (data.isLast()) { @@ -133,16 +112,15 @@ public class NotesListItem extends LinearLayout { } else if (data.isFirst() || data.isMultiFollowingFolder()) { setBackgroundResource(NoteItemBgResources.getNoteBgFirstRes(id)); } else { - setBackgroundResource(NoteItemBgResources.getNoteBgMiddleRes(id)); + setBackgroundResource(NoteItemBgResources.getNoteBgNormalRes(id)); } } else { - // 如果笔记项类型为文件夹,则设置文件夹的背景资源 setBackgroundResource(NoteItemBgResources.getFolderBgRes()); } } // 获取绑定到此 NotesListItem 的数据 public NoteItemData getItemData() { - return mItemData; // 返回存储的当前笔记项数据 + return mItemData; } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java b/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java index 43b301b..48125be 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java +++ b/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package net.micode.notes.ui; - + import android.accounts.Account; import android.accounts.AccountManager; import android.app.ActionBar; @@ -41,74 +41,59 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; - + import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.gtask.remote.GTaskSyncService; - + // 设置界面活动类,继承自PreferenceActivity public class NotesPreferenceActivity extends PreferenceActivity { - // 定义偏好设置文件的名称 public static final String PREFERENCE_NAME = "notes_preferences"; - - // 定义偏好设置中存储同步账户名称的键 + public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name"; - - // 定义偏好设置中存储上次同步时间的键 + public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time"; - - // 定义偏好设置中背景颜色随机出现的键 + public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear"; - - // 定义偏好设置中同步账户键(用于UI显示) + private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key"; - - // 定义过滤器键,用于添加账户设置 + private static final String AUTHORITIES_FILTER_KEY = "authorities"; - - // 定义账户类别,在UI中用于显示账户相关的偏好设置 + private PreferenceCategory mAccountCategory; - - // 定义一个GTaskReceiver实例,用于接收同步状态更新的广播 + private GTaskReceiver mReceiver; - - // 存储原始的Google账户列表 + private Account[] mOriAccounts; - - // 标记用户是否添加了新账户 + private boolean mHasAddedAccount; - + // 创建活动时初始化界面 @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); - - // 设置ActionBar的返回按钮,以便用户可以通过点击应用图标返回上一级活动 + + /* 使用应用图标进行导航 */ getActionBar().setDisplayHomeAsUpEnabled(true); - - // 从指定的XML资源文件加载偏好设置 + addPreferencesFromResource(R.xml.preferences); - // 找到XML中定义的账户类别PreferenceCategory,并赋值给mAccountCategory mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); - // 创建GTaskReceiver实例,并注册广播接收器,用于接收同步服务的状态广播 mReceiver = new GTaskReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); registerReceiver(mReceiver, filter); - - // 初始化账户列表,目前为空,将在其他方法中进行填充 + mOriAccounts = null; - // 创建并添加自定义的头部视图到设置界面,该视图通常用于显示额外的信息或操作 View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); getListView().addHeaderView(header, null, true); } - + // 恢复活动时刷新界面 @Override protected void onResume() { super.onResume(); - + // 如果用户添加了新账户,自动设置同步账户 if (mHasAddedAccount) { Account[] accounts = getGoogleAccounts(); @@ -128,11 +113,10 @@ public class NotesPreferenceActivity extends PreferenceActivity { } } } - - // 刷新用户界面,包括账户偏好设置和同步按钮 + refreshUI(); } - + // 销毁活动时注销广播接收器 @Override protected void onDestroy() { @@ -141,36 +125,26 @@ public class NotesPreferenceActivity extends PreferenceActivity { } super.onDestroy(); } - + // 加载账户偏好设置 private void loadAccountPreference() { - // 清空账户类别中的所有偏好设置项 mAccountCategory.removeAll(); - - // 创建一个新的Preference实例,用于显示账户偏好设置 + Preference accountPref = new Preference(this); - // 获取当前设置的同步账户名称 final String defaultAccount = getSyncAccountName(this); - // 设置偏好设置项的标题 accountPref.setTitle(getString(R.string.preferences_account_title)); - // 设置偏好设置项的摘要信息 accountPref.setSummary(getString(R.string.preferences_account_summary)); - - // 设置偏好设置项的点击监听器 accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override public boolean onPreferenceClick(Preference preference) { - // 如果当前没有正在进行的同步操作 if (!GTaskSyncService.isSyncing()) { - // 如果同步账户名称为空,表示第一次设置账户 if (TextUtils.isEmpty(defaultAccount)) { + // 第一次设置账户 showSelectAccountAlertDialog(); } else { // 如果账户已经设置,提示用户切换账户的风险 showChangeAccountConfirmAlertDialog(); } } else { - // 如果正在同步,显示提示信息,告知用户无法在同步过程中更改账户 Toast.makeText(NotesPreferenceActivity.this, R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT) .show(); @@ -178,49 +152,38 @@ public class NotesPreferenceActivity extends PreferenceActivity { return true; } }); - - // 将账户偏好设置项添加到账户类别中 + mAccountCategory.addPreference(accountPref); } - + // 加载同步按钮 private void loadSyncButton() { - // 找到布局文件中定义的同步按钮 Button syncButton = (Button) findViewById(R.id.preference_sync_button); - // 找到布局文件中定义的上次同步时间显示文本 TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); - - // 根据同步服务的状态设置按钮的文本和点击事件 + + // 设置按钮状态 if (GTaskSyncService.isSyncing()) { - // 如果正在同步,设置按钮文本为取消同步,并添加点击事件以取消同步 syncButton.setText(getString(R.string.preferences_button_sync_cancel)); syncButton.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View v) { GTaskSyncService.cancelSync(NotesPreferenceActivity.this); } }); } else { - // 如果没有同步,设置按钮文本为立即同步,并添加点击事件以开始同步 syncButton.setText(getString(R.string.preferences_button_sync_immediately)); syncButton.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View v) { GTaskSyncService.startSync(NotesPreferenceActivity.this); } }); } - - // 根据同步账户名称是否为空设置按钮是否可用 syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this))); - - // 根据同步服务的状态设置上次同步时间的显示 + + // 设置上次同步时间 if (GTaskSyncService.isSyncing()) { - // 如果正在同步,显示同步进度信息 lastSyncTimeView.setText(GTaskSyncService.getProgressString()); lastSyncTimeView.setVisibility(View.VISIBLE); } else { - // 如果没有同步,显示上次同步的时间,如果没有同步过则不显示 long lastSyncTime = getLastSyncTime(this); if (lastSyncTime != 0) { lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time, @@ -232,83 +195,58 @@ public class NotesPreferenceActivity extends PreferenceActivity { } } } - + // 刷新用户界面 private void refreshUI() { - // 加载账户偏好设置 loadAccountPreference(); - // 加载同步按钮 loadSyncButton(); } - + // 显示选择账户的对话框 private void showSelectAccountAlertDialog() { - // 创建一个AlertDialog.Builder实例 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); - - // 加载自定义的对话框标题布局 + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); - // 设置对话框标题文本 titleTextView.setText(getString(R.string.preferences_dialog_select_account_title)); TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); - // 设置对话框副标题文本 subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips)); - // 设置自定义的对话框标题 + dialogBuilder.setCustomTitle(titleView); - - // 设置对话框的确定按钮为空,因为我们使用自定义视图来处理选择 dialogBuilder.setPositiveButton(null, null); - - // 获取Google账户列表 + Account[] accounts = getGoogleAccounts(); - // 获取当前设置的同步账户名称 String defAccount = getSyncAccountName(this); - - // 保存原始账户列表 + mOriAccounts = accounts; - // 重置标记,表示用户尚未添加新账户 mHasAddedAccount = false; - + if (accounts.length > 0) { - // 创建一个CharSequence数组来存储账户名称 CharSequence[] items = new CharSequence[accounts.length]; - // 由于items是CharSequence数组,需要一个final引用以便在内部类中使用 final CharSequence[] itemMapping = items; int checkedItem = -1; int index = 0; - - // 遍历账户列表,将账户名称存储到items数组中,并标记默认账户 for (Account account : accounts) { if (TextUtils.equals(account.name, defAccount)) { checkedItem = index; } items[index++] = account.name; } - - // 设置对话框为单选列表,包含所有的Google账户 dialogBuilder.setSingleChoiceItems(items, checkedItem, new DialogInterface.OnClickListener() { - @Override public void onClick(DialogInterface dialog, int which) { - // 用户选择账户后,设置同步账户并刷新UI setSyncAccount(itemMapping[which].toString()); dialog.dismiss(); refreshUI(); } }); } - - // 加载添加账户的文本视图布局 + View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null); - // 将添加账户的文本视图添加到对话框中 dialogBuilder.setView(addAccountView); - - // 显示对话框 + final AlertDialog dialog = dialogBuilder.show(); - // 设置添加账户文本视图的点击事件,启动系统的添加账户设置界面 addAccountView.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View v) { mHasAddedAccount = true; Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS"); @@ -320,194 +258,145 @@ public class NotesPreferenceActivity extends PreferenceActivity { } }); } - + // 显示更改账户确认对话框 private void showChangeAccountConfirmAlertDialog() { - // 创建一个AlertDialog.Builder实例 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); - - // 加载自定义的对话框标题布局 + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); - // 设置对话框标题文本,包括当前同步账户名称 titleTextView.setText(getString(R.string.preferences_dialog_change_account_title, getSyncAccountName(this))); TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); - // 设置对话框副标题文本,警告用户切换账户可能带来的风险 subtitleTextView.setText(getString(R.string.preferences_dialog_change_account_warn_msg)); - // 设置自定义的对话框标题 dialogBuilder.setCustomTitle(titleView); - - // 创建一个CharSequence数组来存储对话框中的菜单项 + CharSequence[] menuItemArray = new CharSequence[] { getString(R.string.preferences_menu_change_account), getString(R.string.preferences_menu_remove_account), getString(R.string.preferences_menu_cancel) }; - - // 设置对话框的菜单项 dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() { - @Override public void onClick(DialogInterface dialog, int which) { - // 根据用户选择的菜单项执行相应的操作 if (which == 0) { - // 如果用户选择更改账户,显示选择账户对话框 showSelectAccountAlertDialog(); } else if (which == 1) { - // 如果用户选择移除账户,移除同步账户并刷新UI removeSyncAccount(); refreshUI(); } } }); - - // 显示对话框 dialogBuilder.show(); } - + // 获取Google账户列表 private Account[] getGoogleAccounts() { - // 获取AccountManager实例 AccountManager accountManager = AccountManager.get(this); - // 返回所有类型为"com.google"的账户 return accountManager.getAccountsByType("com.google"); } - + // 设置同步账户 private void setSyncAccount(String account) { - // 如果当前设置的同步账户名称与新的账户名称不同 if (!getSyncAccountName(this).equals(account)) { - // 获取SharedPreferences实例 SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); - - // 如果新的账户名称不为空,则将其存储到偏好设置中 if (account != null) { editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, account); } else { - // 如果新的账户名称为空,则将其设置为空字符串 editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); } - // 提交偏好设置更改 editor.commit(); - + // 清除上次同步时间 setLastSyncTime(this, 0); - + // 清除本地Gtask相关信息 new Thread(new Runnable() { - @Override public void run() { ContentValues values = new ContentValues(); - // 将Gtask ID和SYNC ID设置为空和0 values.put(NoteColumns.GTASK_ID, ""); values.put(NoteColumns.SYNC_ID, 0); - // 更新本地Notes数据库中的相关字段 getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); } }).start(); - - // 显示成功设置账户的提示信息 + Toast.makeText(NotesPreferenceActivity.this, getString(R.string.preferences_toast_success_set_accout, account), Toast.LENGTH_SHORT).show(); } } - + // 移除同步账户 private void removeSyncAccount() { - // 获取SharedPreferences实例 SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); - - // 如果偏好设置中包含同步账户名称,则将其移除 if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) { editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME); } - // 如果偏好设置中包含上次同步时间,则将其移除 if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) { editor.remove(PREFERENCE_LAST_SYNC_TIME); } - // 提交偏好设置更改 editor.commit(); - + // 清除本地Gtask相关信息 new Thread(new Runnable() { - @Override public void run() { ContentValues values = new ContentValues(); - // 将Gtask ID和SYNC ID设置为空和0 values.put(NoteColumns.GTASK_ID, ""); values.put(NoteColumns.SYNC_ID, 0); - // 更新本地Notes数据库中的相关字段 getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); } }).start(); } - + // 获取同步账户名称 public static String getSyncAccountName(Context context) { - // 获取SharedPreferences实例 SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); - // 返回存储的同步账户名称,如果未设置则返回空字符串 return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); } - + // 设置上次同步时间 public static void setLastSyncTime(Context context, long time) { - // 获取SharedPreferences实例 SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); - - // 将上次同步时间存储到偏好设置中 editor.putLong(PREFERENCE_LAST_SYNC_TIME, time); - // 提交偏好设置更改 editor.commit(); } - + // 获取上次同步时间 public static long getLastSyncTime(Context context) { - // 获取SharedPreferences实例 SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); - // 返回存储的上次同步时间,如果未设置则返回0 return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0); } - + // 广播接收器,用于接收同步状态更新 private class GTaskReceiver extends BroadcastReceiver { - // 接收到广播时执行的操作 + @Override public void onReceive(Context context, Intent intent) { - // 刷新用户界面,包括账户偏好设置和同步按钮 refreshUI(); - - // 如果广播中包含同步正在进行的标志 if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) { - // 找到布局文件中定义的上次同步时间显示文本 TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview); - // 更新文本为同步进度信息 syncStatus.setText(intent .getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG)); } + } } - + // 选项菜单项点击事件处理 - @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: - // 如果用户点击了返回按钮,启动NotesListActivity并清除当前活动栈中的其他活动 Intent intent = new Intent(this, NotesListActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; default: - // 对于其他选项,返回false表示不处理 return false; } } -} +} \ No newline at end of file