From 068b14af6df0dc37fc981ecf415d42e7b7ef4dd6 Mon Sep 17 00:00:00 2001 From: ZhaoJie <207594601@qq.com> Date: Tue, 25 Apr 2023 22:37:41 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=B5=E6=9D=B0ui=E5=8C=85=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../micode/notes/ui/AlarmAlertActivity.java | 9 ++ .../micode/notes/ui/AlarmInitReceiver.java | 3 + .../net/micode/notes/ui/AlarmReceiver.java | 2 + .../net/micode/notes/ui/DateTimePicker.java | 45 ++++++++-- .../micode/notes/ui/DateTimePickerDialog.java | 4 + .../net/micode/notes/ui/DropdownMenu.java | 8 +- .../micode/notes/ui/FoldersListAdapter.java | 5 ++ .../net/micode/notes/ui/NoteEditActivity.java | 68 ++++++++++---- .../net/micode/notes/ui/NoteEditText.java | 10 ++- .../micode/notes/ui/NotesListActivity.java | 88 +++++++++++++------ .../net/micode/notes/ui/NotesListAdapter.java | 29 +++--- .../net/micode/notes/ui/NotesListItem.java | 1 + .../notes/ui/NotesPreferenceActivity.java | 16 ++-- 13 files changed, 211 insertions(+), 77 deletions(-) diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java index 85723be..280ae78 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java @@ -60,6 +60,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); } +// 在Activity创建时被调用,它首先设置Activity的特性,然后获取传递过来的Intent,从中获取提醒的ID和摘录信息,并根据提醒的ID判断提醒是否可以在Note数据库中找到,并显示对应的提醒对话框和播放提醒声音。 Intent intent = getIntent(); @@ -82,11 +83,14 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD finish(); } } +// 以一个try-catch块开始,尝试从意图中提取一个笔记ID,使用笔记ID从内容提供程序中检索与该笔记相关的文本片段,并在文本片段太长时截断它。如果在此过程中抛出IllegalArgumentException异常,则捕获该异常并返回方法。 +//接下来的代码块创建一个新的MediaPlayer对象,并检查与笔记ID关联的笔记是否在笔记数据库中可见。如果可见,则调用名为showActionDialog()的方法,该方法可能显示一个对话框给用户。还调用了playAlarmSound()方法,该方法可能会播放警报声。如果笔记在数据库中不可见,则方法仅完成而不显示对话框或播放声音。 private boolean isScreenOn() { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); return pm.isScreenOn(); } +// 用于判断屏幕是否打开。 private void playAlarmSound() { Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); @@ -118,6 +122,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD e.printStackTrace(); } } +// 用于播放提醒声音,首先获取系统默认的闹铃铃声,然后判断当前是否为静音模式,如果是,则设置MediaPlayer的音频流类型为系统当前可影响铃声的流,否则设置为闹钟流类型。最后设置铃声数据源、循环播放并开始播放。 private void showActionDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(this); @@ -129,6 +134,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } dialog.show().setOnDismissListener(this); } +// 用于显示提醒对话框,其中包含提醒的摘录信息和两个按钮(确认和进入)。 public void onClick(DialogInterface dialog, int which) { switch (which) { @@ -142,11 +148,13 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD break; } } +// 用于处理对话框中按钮的点击事件,如果是进入按钮,则启动NoteEditActivity并携带提醒的ID,将它作为Extra参数传递给NoteEditActivity以便打开对应的Note。如果是确认按钮,则什么都不做。 public void onDismiss(DialogInterface dialog) { stopAlarmSound(); finish(); } +// 用于处理提醒对话框关闭事件,停止播放提醒声音并结束Activity。 private void stopAlarmSound() { if (mPlayer != null) { @@ -156,3 +164,4 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } } } +// 用于停止播放提醒声音。 diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java index f221202..5b41fe2 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -28,6 +28,8 @@ import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; +//这里定义了一个包名为net.micode.notes.ui的Java类AlarmInitReceiver,它继承了BroadcastReceiver类。引入了Android系统提供的AlarmManager、PendingIntent、BroadcastReceiver、ContentUris等类。还引入了笔记相关的数据模型Notes和NoteColumns。 +//PROJECTION是笔记查询时的投影,指定了需要查询的列。COLUMN_ID和COLUMN_ALERTED_DATE则是笔记查询结果中对应的列索引。 public class AlarmInitReceiver extends BroadcastReceiver { private static final String [] PROJECTION = new String [] { @@ -62,4 +64,5 @@ public class AlarmInitReceiver extends BroadcastReceiver { c.close(); } } +// onReceive方法是接收广播后执行的方法。在这里,首先获取当前时间戳currentDate,然后通过getContentResolver().query方法查询所有需要提醒的笔记,查询条件是提醒时间大于当前时间戳并且类型是笔记类型。 } diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java index 54e503b..a485c43 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java @@ -27,4 +27,6 @@ public class AlarmReceiver extends BroadcastReceiver { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } +// onReceive方法中,首先获取传入的Intent对象,并通过setClass方法将Intent的目标Activity设置为AlarmAlertActivity。然后通过addFlags方法设置Intent的标志位FLAG_ACTIVITY_NEW_TASK,表示启动一个新的Task来显示Activity。最后通过context.startActivity方法启动Activity。 } +//这段代码的作用是在系统闹钟触发时,启动AlarmAlertActivity来显示提醒内容。 \ No newline at end of file diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java index 496b0cd..9440fe4 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java @@ -67,9 +67,9 @@ public class DateTimePicker extends FrameLayout { private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); - updateDateControl(); - onDateTimeChanged(); + mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal);// 使用Calendar类的add方法将mDate对象的日期字段(即Calendar.DAY_OF_YEAR)增加newVal - oldVal天,以更新日期。 + updateDateControl();//调用updateDateControl方法,该方法用来更新日期控件的显示。 + onDateTimeChanged();//调用onDateTimeChanged方法,该方法用来通知其他组件该日期时间已经发生了变化。 } }; @@ -104,16 +104,20 @@ public class DateTimePicker extends FrameLayout { isDateChanged = true; } } +// 根据24小时制或12小时制以及上下午状态等情况,计算新的时间并更新到mDate字段中。 int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); mDate.set(Calendar.HOUR_OF_DAY, newHour); onDateTimeChanged(); +// 调用onDateTimeChanged方法,该方法用来通知其他组件该日期时间已经发生了变化。 if (isDateChanged) { setCurrentYear(cal.get(Calendar.YEAR)); setCurrentMonth(cal.get(Calendar.MONTH)); setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); } +// 如果日期发生了变化,则调用setCurrentYear和setCurrentMonth方法更新年份和月份控件的显示。 } }; +// 这段代码定义了一个监听器对象,用于监听小时NumberPicker控件的值变化事件。 private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override @@ -126,6 +130,7 @@ public class DateTimePicker extends FrameLayout { } else if (oldVal == minValue && newVal == maxValue) { offset -= 1; } +// 当监听器被触发时,它首先根据 NumberPicker 的旧值和新值计算出一个 offset。如果旧值是最大值且新值是最小值,则将 offset 增加1。如果旧值是最小值且新值是最大值,则将 offset 减少1。 if (offset != 0) { mDate.add(Calendar.HOUR_OF_DAY, offset); mHourSpinner.setValue(getCurrentHour()); @@ -139,10 +144,13 @@ public class DateTimePicker extends FrameLayout { updateAmPmControl(); } } +// 如果 offset 不为0,则监听器会更新 mDate 变量,将 offset 添加到小时数中,将小时选择器的值设置为当前小时,调用 updateDateControl() 更新日期控件,并根据新的小时数更新 AM/PM 控件。 mDate.set(Calendar.MINUTE, newVal); onDateTimeChanged(); +// 更新 mDate 变量后,监听器将分钟值设置为新值,并调用 onDateTimeChanged() 通知任何监听器日期和时间已更新。 } }; +// 定义了一个私有字段 mOnMinuteChangedListener,它是 NumberPicker.OnValueChangeListener 的一个实例。当表示分钟的 NumberPicker 的值发生变化时,此监听器将被触发。 private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { @Override @@ -156,12 +164,16 @@ public class DateTimePicker extends FrameLayout { updateAmPmControl(); onDateTimeChanged(); } +// 当监听器被触发时,它将 mIsAm 变量取反,表示用户选择了 AM 还是 PM。如果 mIsAm 是 true,则说明用户选择了 AM,此时监听器将 mDate 变量减去半天的小时数。如果 mIsAm 是 false,则说明用户选择了 PM,此时监听器将 mDate 变量加上半天的小时数。然后,监听器会调用 updateAmPmControl() 更新 AM/PM 控件,并调用 onDateTimeChanged() 通知任何监听器日期和时间已更新。 }; +// 定义了一个私有字段 mOnAmPmChangedListener,它是 NumberPicker.OnValueChangeListener 的一个实例。当表示 AM/PM 的 NumberPicker 的值发生变化时,此监听器将被触发。 public interface OnDateTimeChangedListener { void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute); +// 该接口有一个抽象方法 onDateTimeChanged(),它在日期或时间发生变化时被调用。该方法接收 6 个参数:view 表示当前 DateTimePicker 实例,year 表示年份,month 表示月份(从 0 开始),dayOfMonth 表示月中的某一天,hourOfDay 表示小时数(24 小时制),minute 表示分钟数。 } +//定义了一个接口 OnDateTimeChangedListener,它用于监听日期和时间的变化。当日期或时间发生变化时,可以调用该接口的 onDateTimeChanged() 方法通知任何实现该接口的监听器。通过实现该接口并在需要的地方注册监听器,可以在日期或时间发生变化时执行自定义操作,例如更新 UI 或执行某些计算。 public DateTimePicker(Context context) { this(context, System.currentTimeMillis()); @@ -173,15 +185,18 @@ public class DateTimePicker extends FrameLayout { public DateTimePicker(Context context, long date, boolean is24HourView) { super(context); + mDate = Calendar.getInstance(); mInitialising = true; mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; inflate(context, R.layout.datetime_picker, this); +// 首先调用了父类 ViewGroup 的构造函数 super(context) 来初始化 DateTimePicker 实例。然后,代码使用 Calendar.getInstance() 获取一个 Calendar 对象,该对象表示当前日期和时间。变量 mIsAm 被初始化为当前小时数是否大于等于 12,以确定当前用户选择的是 AM 还是 PM。 mDateSpinner = (NumberPicker) findViewById(R.id.date); mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); +// 获取了布局文件中 ID 为 date 的 NumberPicker 控件,并将其赋值给 mDateSpinner 变量。然后,使用 setMinValue() 和 setMaxValue() 方法将 mDateSpinner 的最小值和最大值分别设置为 DATE_SPINNER_MIN_VAL 和 DATE_SPINNER_MAX_VAL。使用 setOnValueChangedListener() 方法将 mDateSpinner 的值更改监听器设置为 mOnDateChangedListener。这意味着当 mDateSpinner 的值更改时,将会调用 mOnDateChangedListener 中的方法来处理这个事件。 mHourSpinner = (NumberPicker) findViewById(R.id.hour); mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); @@ -190,13 +205,18 @@ public class DateTimePicker extends FrameLayout { mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); mMinuteSpinner.setOnLongPressUpdateInterval(100); mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); +// 获取了布局文件中 ID 为 hour 和 minute 的 NumberPicker 控件,并将它们分别赋值给 mHourSpinner 和 mMinuteSpinner 变量。然后,使用 setOnValueChangedListener() 方法将 mHourSpinner 和 mMinuteSpinner 控件的值更改监听器分别设置为 mOnHourChangedListener 和 mOnMinuteChangedListener。 +// 接下来,使用 setMinValue() 和 setMaxValue() 方法将 mMinuteSpinner 的最小值和最大值分别设置为 MINUT_SPINNER_MIN_VAL 和 MINUT_SPINNER_MAX_VAL,以限制分钟选择器的范围。 +// 最后,使用 setOnLongPressUpdateInterval() 方法将 mMinuteSpinner 的长按更新间隔设置为 100 毫秒。这意味着当用户长按 mMinuteSpinner 中的增加或减少按钮时,它将以每 100 毫秒的速度连续增加或减少 mMinuteSpinner 的值。 +// 通过设置 NumberPicker 的值更改监听器和其他属性,代码实现了一个可以选择小时和分钟的控件,并将它们分别绑定到 mHourSpinner 和 mMinuteSpinner 变量上,以便在之后的操作中使用。 - String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); + String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();//获取了当前设备的日期格式符号,并使用 getAmPmStrings() 方法从中获取 AM/PM 格式符号的字符串数组,并将其赋值给 stringsForAmPm 变量。 mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); - mAmPmSpinner.setDisplayedValues(stringsForAmPm); - mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); +// 获取了布局文件中 ID 为 amPm 的 NumberPicker 控件,并将其赋值给 mAmPmSpinner 变量。使用 setMinValue() 和 setMaxValue() 方法将 mAmPmSpinner 的最小值和最大值分别设置为 AMPM_SPINNER_MIN_VAL 和 AMPM_SPINNER_MAX_VAL,以限制 AM/PM 选择器的范围。 + mAmPmSpinner.setDisplayedValues(stringsForAmPm);//使用 setDisplayedValues() 方法将 stringsForAmPm 数组设置为 mAmPmSpinner 的显示值。这意味着 AM/PM 选择器将显示 stringsForAmPm 数组中的字符串,而不是默认的数字值。 + mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener);//使用 setOnValueChangedListener() 方法将 mAmPmSpinner 的值更改监听器设置为 mOnAmPmChangedListener。这意味着当用户更改 AM/PM 选择器的值时,将调用 mOnAmPmChangedListener 中的方法来处理这个事件。 // update controls to initial state updateDateControl(); @@ -204,6 +224,7 @@ public class DateTimePicker extends FrameLayout { updateAmPmControl(); set24HourView(is24HourView); +// 代码调用了 updateDateControl()、updateHourControl() 和 updateAmPmControl() 方法,以便将控件显示为当前日期和时间的值。然后,代码调用了 set24HourView() 方法将选择器的时间格式设置为 24 小时制或 12 小时制。 // set to current time setCurrentDate(date); @@ -212,6 +233,7 @@ public class DateTimePicker extends FrameLayout { // set the content descriptions mInitialising = false; +// 调用了 setCurrentDate() 方法将选择器的日期和时间设置为指定的日期和时间,调用 setEnabled() 方法将选择器的可用状态设置为指定的值,并将 mInitialising 标志设置为 false,以便通知选择器已完成初始化。 } @Override @@ -219,13 +241,17 @@ public class DateTimePicker extends FrameLayout { if (mIsEnabled == enabled) { return; } +// 当调用 setEnabled() 方法时,如果传入的参数 enabled 与当前的 mIsEnabled 变量的值相同,说明选择器的可用状态没有发生变化,直接返回即可。 super.setEnabled(enabled); mDateSpinner.setEnabled(enabled); mMinuteSpinner.setEnabled(enabled); mHourSpinner.setEnabled(enabled); mAmPmSpinner.setEnabled(enabled); mIsEnabled = enabled; +// 代码首先调用父类的 setEnabled() 方法,将整个时间选择器的可用状态设置为传入的参数 enabled。然后,分别调用 mDateSpinner、mMinuteSpinner、mHourSpinner 和 mAmPmSpinner 的 setEnabled() 方法,将它们的可用状态也设置为传入的参数 enabled。 +//最后,将 mIsEnabled 变量的值设置为传入的参数 enabled,以便在下一次调用 setEnabled() 方法时使用。 } +// 重写 setEnabled() 方法,代码实现了一个可以同时设置整个时间选择器的可用状态的功能。 @Override public boolean isEnabled() { @@ -428,11 +454,14 @@ public class DateTimePicker extends FrameLayout { } mIs24HourView = is24HourView; mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); +// 当传入的参数 is24HourView 与当前的 mIs24HourView 变量的值相同时,方法直接返回。否则,将 mIs24HourView 变量的值设置为传入的参数 is24HourView,表示时间选择器的显示格式已经更改。 int hour = getCurrentHourOfDay(); updateHourControl(); setCurrentHour(hour); updateAmPmControl(); +// 获取当前的小时数并调用 updateHourControl() 方法更新小时选择器,以保持小时选择器的一致性。接着,使用 setCurrentHour() 方法将当前的小时数设置回时间选择器,并调用 updateAmPmControl() 方法更新 AM/PM 选择器。 } +//通过设置 AM/PM 选择器的可见性和更新时间选择器的小时控件和 AM/PM 控件,代码实现了一个可以切换时间选择器显示格式的功能。 private void updateDateControl() { Calendar cal = Calendar.getInstance(); @@ -447,6 +476,8 @@ public class DateTimePicker extends FrameLayout { mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); mDateSpinner.invalidate(); } +// 用于更新日期选择器的显示值。它首先获取当前日期并将其设置为日历实例 cal 的时间。然后,cal 被设置为一周的第一天,以确保日期选择器显示一周的日期。 +//接下来,使用 setDisplayedValues() 方法将日期选择器的显示值设置为 null,以便重新生成新的日期显示值。然后,使用循环从 cal 中获取每一天的日期,并将其格式化为 MM.dd EEEE 的格式,并将其存储在一个字符串数组中。最后,使用 setDisplayedValues() 方法将新的日期显示值设置为 mDateSpinner,并将当前选择的日期值设置为一周的中间值,以保持日期选择器的一致性。 private void updateAmPmControl() { if (mIs24HourView) { @@ -457,6 +488,7 @@ public class DateTimePicker extends FrameLayout { mAmPmSpinner.setVisibility(View.VISIBLE); } } +// 用于更新 AM/PM 选择器的显示值。如果时间选择器为 24 小时格式,则将 AM/PM 选择器隐藏;否则,根据当前是否为 AM,将 AM/PM 选择器的值设置为 Calendar.AM 或 Calendar.PM,并将其可见性设置为 View.VISIBLE。 private void updateHourControl() { if (mIs24HourView) { @@ -467,6 +499,7 @@ public class DateTimePicker extends FrameLayout { mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); } } +// 用于更新小时选择器的显示值。如果时间选择器为 24 小时格式,则将小时选择器的最小值和最大值分别设置为 HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW 和 HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW;否则,将小时选择器的最小值和最大值分别设置为 HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW 和 HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW。 /** * Set the callback that indicates the 'Set' button has been pressed. diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..a7c67ce 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -39,6 +39,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } +// 实现了一个 OnDateTimeSetListener 接口,该接口定义了一个 OnDateTimeSet() 方法,用于在用户选择日期时间后通知调用者。 public DateTimePickerDialog(Context context, long date) { super(context); @@ -55,6 +56,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener updateTitle(mDate.getTimeInMillis()); } }); +// 包含了一个 DateTimePicker 控件,用于让用户选择日期和时间。通过 mDateTimePicker.setOnDateTimeChangedListener() 方法,当用户选择日期和时间时,将更新 mDate 的值,并使用 updateTitle() 方法更新对话框的标题。 mDate.setTimeInMillis(date); mDate.set(Calendar.SECOND, 0); mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); @@ -67,6 +69,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener public void set24HourView(boolean is24HourView) { mIs24HourView = is24HourView; } +//set24HourView() 方法,用于设置日期时间选择器是否为 24 小时格式。默认情况下,该值将由系统的设置决定。 public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; @@ -86,5 +89,6 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } } +// 重写了 onClick() 方法,以便在用户点击“确定”按钮后,将用户选择的日期时间作为参数传递到 OnDateTimeSet() 方法中,从而通知调用者。 } \ No newline at end of file diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java b/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java index 613dc74..44cca84 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java @@ -31,6 +31,7 @@ public class DropdownMenu { private Button mButton; private PopupMenu mPopupMenu; private Menu mMenu; +// 一个 Button 控件,用于显示菜单的标题,以及一个 PopupMenu 对象,用于显示菜单项。在构造函数中,该类接受一个菜单资源 ID,并使用 mPopupMenu.getMenuInflater().inflate() 方法从 XML 资源中加载菜单项,然后将菜单项添加到 mMenu 对象中。 public DropdownMenu(Context context, Button button, int menuId) { mButton = button; @@ -43,19 +44,22 @@ public class DropdownMenu { mPopupMenu.show(); } }); +// 重写了 setOnClickListener() 方法,以便在用户点击 Button 控件时显示下拉菜单。 } +// 在 Button 控件上注册一个单击事件监听器,并在该监听器中实现下拉菜单的显示逻辑。 public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); } } +// setOnDropdownMenuItemClickListener() 方法,用于设置菜单项的点击监听器。通过这个方法,应用程序可以在用户选择菜单项时执行相应的操作。 public MenuItem findItem(int id) { return mMenu.findItem(id); - } + }//findItem() 方法用于查找指定 ID 的菜单项 public void setTitle(CharSequence title) { mButton.setText(title); - } + }//用于设置菜单的标题。 } diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java b/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java index 96b77da..71a4f49 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java @@ -47,6 +47,7 @@ public class FoldersListAdapter extends CursorAdapter { public View newView(Context context, Cursor cursor, ViewGroup parent) { return new FolderListItem(context); } +// 用于创建新的视图,该方法返回一个新的 FolderListItem 对象,它是一个自定义的 LinearLayout,用于显示文件夹列表项的布局。 @Override public void bindView(View view, Context context, Cursor cursor) { @@ -56,12 +57,14 @@ public class FoldersListAdapter extends CursorAdapter { ((FolderListItem) view).bind(folderName); } } +// 用于绑定视图和数据,该方法会将数据从 Cursor 对象中读取出来,并将其绑定到 FolderListItem 视图中。 public String getFolderName(Context context, int position) { Cursor cursor = (Cursor) getItem(position); return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); } +// 获取文件夹列表中某个位置的文件夹名称。 private class FolderListItem extends LinearLayout { private TextView mName; @@ -76,5 +79,7 @@ public class FoldersListAdapter extends CursorAdapter { mName.setText(name); } } +// FolderListItem 类是一个自定义的 LinearLayout,用于显示文件夹列表项的布局。它包含一个 TextView 控件,用于显示文件夹名称。 } +//这段代码是一个自定义的 CursorAdapter 类 FoldersListAdapter,用于在 Android 应用程序中显示一个文件夹列表。 diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 387c03a..93df003 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -63,7 +63,6 @@ import net.micode.notes.tool.ResourceParser.TextAppearanceResources; 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_3x; import net.micode.notes.widget.NoteWidgetProvider_4x; import java.util.HashMap; @@ -84,6 +83,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, public ImageView ibSetBgColor; } +// HeadViewHolder类定义了一组视图,用于在列表或网格中显示信息。这些视图包括一个TextView用于显示修改信息,一个ImageView用于显示警报图标,另一个TextView用于显示警报日期,还有一个ImageView用于选择背景颜色。 private static final Map sBgSelectorBtnsMap = new HashMap(); static { @@ -102,6 +102,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select); sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); } +// sBgSelectorBtnsMap是一个HashMap,将用于选择背景颜色的ImageView视图的资源ID映射到整数值,这些整数值在ResourceParser类中定义。同样,sBgSelectorSelectionMap将整数值映射到所选ImageView视图的资源ID。 private static final Map sFontSizeBtnsMap = new HashMap(); static { @@ -118,6 +119,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); } +// sFontSizeBtnsMap将用于选择字体大小的LinearLayout视图的资源ID映射到整数值,而sFontSelectorSelectionMap将整数值映射到所选ImageView视图的资源ID。 private static final String TAG = "NoteEditActivity"; @@ -185,10 +187,14 @@ public class NoteEditActivity extends Activity implements OnClickListener, * If the user specified the {@link Intent#ACTION_VIEW} but not provided with id, * then jump to the NotesListActivity */ - mWorkingNote = null; +// 果用户指定了 Intent.ACTION_VIEW 动作但没有提供ID,则跳转到 NotesListActivity + mWorkingNote = null;//在方法中,首先将mWorkingNote设置为null。然后,根据传入的Intent的动作(action)进行选择。 if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { +// Intent中获取笔记ID long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); + // 将用户查询字符串设置为空 mUserQuery = ""; + // 如果Intent包含了搜索结果的额外数据,则从额外数据中获取笔记ID,并将用户查询字符串设置为搜索管理器中的用户查询字符串 /** * Starting from the searched result @@ -198,6 +204,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); } + // 如果笔记在笔记数据库中不存在,则跳转到 NotesListActivity 并显示错误信息的Toast,最后结束 Activity 并返回 false if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) { Intent jump = new Intent(this, NotesListActivity.class); startActivity(jump); @@ -205,6 +212,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, finish(); return false; } else { + // 加载笔记 mWorkingNote = WorkingNote.load(this, noteId); if (mWorkingNote == null) { Log.e(TAG, "load note failed with note id" + noteId); @@ -212,11 +220,12 @@ public class NoteEditActivity extends Activity implements OnClickListener, return false; } } +// 如果该Intent的动作(action)为Intent.ACTION_VIEW,则从该Intent中获取笔记的ID(noteId)。如果该Intent还包含了一个搜索结果(Search)的额外数据(extra data key),则将noteId从额外数据中获取,并将用户查询字符串(mUserQuery)设置为搜索管理器中的用户查询字符串(SearchManager.USER_QUERY)。如果noteId在笔记数据库中不存在,则将Activity转到NotesListActivity,并显示一个错误信息的Toast,最后结束Activity并返回false。如果noteId在笔记数据库中存在,则加载该笔记的工作副本(mWorkingNote),如果加载失败,则结束Activity并返回false。 getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { - // New note + // New note 如果用户指定了 Intent.ACTION_INSERT_OR_EDIT 动作,则获取笔记ID,如果笔记ID存在,则加载笔记,否则,创建一个新的笔记 long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); @@ -270,20 +279,26 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private void initNoteScreen() { + // 使用mFontSizeId设置笔记编辑器的文本外观。 mNoteEditor.setTextAppearance(this, TextAppearanceResources .getTexAppearanceResource(mFontSizeId)); + // 如果mWorkingNote的CheckListMode为TextNote.MODE_CHECK_LIST,则将编辑器转换为列表模式。 if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { switchToListMode(mWorkingNote.getContent()); } else { + // 如果mWorkingNote的CheckListMode不是TextNote.MODE_CHECK_LIST,则在编辑器中显示笔记内容,并使用mUserQuery高亮显示查询结果。 mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); mNoteEditor.setSelection(mNoteEditor.getText().length()); } + // 隐藏背景选择器中所有不在sBgSelectorSelectionMap中的ID的视图。 for (Integer id : sBgSelectorSelectionMap.keySet()) { findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE); } + // 设置mHeadViewPanel和mNoteEditorPanel的背景颜色为mWorkingNote的标题背景ID和背景颜色ID。 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 @@ -297,6 +312,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private void showAlertHeader() { + // 如果mWorkingNote具有闹钟提醒,则检查当前时间是否超过提醒时间,如果超过,则在标题栏中显示“note_alert_expired”文本;否则,在标题栏中显示相对时间。 if (mWorkingNote.hasClockAlert()) { long time = System.currentTimeMillis(); if (time > mWorkingNote.getAlertDate()) { @@ -305,9 +321,11 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS)); } + // 将标题栏中的提醒日期文本和提醒图标设置为可见。 mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); } else { + // 如果mWorkingNote没有闹钟提醒,则将标题栏中的提醒日期文本和提醒图标设置为不可见。 mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); }; @@ -336,25 +354,30 @@ public class NoteEditActivity extends Activity implements OnClickListener, @Override public boolean dispatchTouchEvent(MotionEvent ev) { + // 如果笔记背景颜色选择器可见,并且触摸事件不在笔记背景颜色选择器范围内,则隐藏笔记背景颜色选择器并返回true。 if (mNoteBgColorSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mNoteBgColorSelector, ev)) { mNoteBgColorSelector.setVisibility(View.GONE); return true; } + // 如果字体大小选择器可见,并且触摸事件不在字体大小选择器范围内,则隐藏字体大小选择器并返回true。 if (mFontSizeSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mFontSizeSelector, ev)) { mFontSizeSelector.setVisibility(View.GONE); return true; } + // 返回父类的dispatchTouchEvent方法。 return super.dispatchTouchEvent(ev); } private boolean inRangeOfView(View view, MotionEvent ev) { + // 获取视图在屏幕上的位置。 int []location = new int[2]; view.getLocationOnScreen(location); int x = location[0]; int y = location[1]; + // 如果触摸事件的x坐标小于视图的x坐标、大于视图的宽度和x坐标之和、y坐标小于视图的y坐标、或大于视图的高度和y坐标之和,则返回false,否则返回true。 if (ev.getX() < x || ev.getX() > (x + view.getWidth()) || ev.getY() < y @@ -405,7 +428,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); } clearSettingState(); - } + }//onPause()方法在活动即将暂停时被调用。如果有任何更改,它会保存当前笔记,并清除任何设置状态。 private void updateWidget() { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); @@ -413,10 +436,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, intent.setClass(this, NoteWidgetProvider_2x.class); } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) { intent.setClass(this, NoteWidgetProvider_4x.class); - } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_3X) { - intent.setClass(this, NoteWidgetProvider_3x.class); } else { - Log.e(TAG, "Unsupported widget type"); + Log.e(TAG, "Unspported widget type"); return; } @@ -426,14 +447,16 @@ public class NoteEditActivity extends Activity implements OnClickListener, sendBroadcast(intent); setResult(RESULT_OK, intent); - } + }//updateWidget()方法更新与当前笔记相关联的小部件。它创建一个意图,并根据笔记的小部件类型设置相应的小部件提供程序类。然后它发送一个广播,带有小部件ID以更新小部件。 + + public void onClick(View v) { int id = v.getId(); if (id == R.id.btn_set_bg_color) { mNoteBgColorSelector.setVisibility(View.VISIBLE); findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( - View.VISIBLE); + - View.VISIBLE); } else if (sBgSelectorBtnsMap.containsKey(id)) { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.GONE); @@ -453,7 +476,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } mFontSizeSelector.setVisibility(View.GONE); } - } + }//onClick()方法处理UI中各种按钮的点击事件。当单击相应的按钮时,它会显示颜色选择器或字体大小选择器。它还根据所选选项更新笔记的字体大小或背景颜色。 @Override public void onBackPressed() { @@ -463,7 +486,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, saveNote(); super.onBackPressed(); - } + }//onBackPressed()方法在按下返回按钮时被调用。它检查当前是否有任何设置状态处于活动状态,并清除它。然后它保存当前笔记并调用超类实现。 private boolean clearSettingState() { if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { @@ -474,14 +497,14 @@ public class NoteEditActivity extends Activity implements OnClickListener, return true; } return false; - } + }//clearSettingState()方法检查当前是否有任何设置状态处于活动状态,并清除它。 public void onBackgroundColorChanged() { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.VISIBLE); mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); - } + }//onBackgroundColorChanged()方法在选择新的背景颜色时被调用。它更新笔记的背景颜色,并更新颜色选择器的颜色。 @Override public boolean onPrepareOptionsMenu(Menu menu) { @@ -506,7 +529,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, menu.findItem(R.id.menu_delete_remind).setVisible(false); } return true; - } + }//onFontSizeChanged()方法在选择新的字体大小时被调用。它更新笔记的字体大小,并更新字体大小选择器的值。 @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -575,7 +598,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, intent.putExtra(Intent.EXTRA_TEXT, info); intent.setType("text/plain"); context.startActivity(intent); - } + }//sendTo(Context context, String info)方法创建一个新的意图,并使用Intent.EXTRA_TEXT将信息作为文本传递。它的目的是启动共享对话框,让用户分享笔记的内容。 + private void createNewNote() { // Firstly, save current editing notes @@ -587,7 +611,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, intent.setAction(Intent.ACTION_INSERT_OR_EDIT); intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId()); startActivity(intent); - } + }//createNewNote()方法保存当前正在编辑的笔记,然后启动一个新的NoteEditActivity以创建一个新的笔记。通过设置Intent.ACTION_INSERT_OR_EDIT和Notes.INTENT_EXTRA_FOLDER_ID,该方法指示NoteEditActivity启动以插入或编辑笔记,并指定所选文件夹的ID。 private void deleteCurrentNote() { if (mWorkingNote.existInDatabase()) { @@ -609,11 +633,11 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } mWorkingNote.markDeleted(true); - } + }//deleteCurrentNote()方法删除当前笔记。如果该笔记已存储在数据库中,则将其从数据库中删除。如果应用程序处于同步模式下,则将其移动到垃圾文件夹中,而不是永久删除。无论是删除还是移动,该方法都会将当前笔记标记为已删除。 private boolean isSyncMode() { return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; - } + }//isSyncMode()方法检查应用程序是否处于同步模式。如果已经选择了同步帐户,则返回true。否则,返回false。 public void onClockAlertChanged(long date, boolean set) { /** @@ -648,6 +672,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, public void onWidgetChanged() { updateWidget(); } +// onWidgetChanged()方法会在小部件更改时被调用。它会调用updateWidget()方法来更新小部件。 public void onEditTextDelete(int index, String text) { int childCount = mEditTextList.getChildCount(); @@ -674,6 +699,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit.requestFocus(); edit.setSelection(length); } +// onEditTextDelete(int index, String text)方法会在删除NoteEditText视图时被调用。该方法首先检查是否只有一个NoteEditText视图存在,如果是则直接返回。然后,该方法会将所有后续视图的索引递减1。接下来,该方法会删除指定索引处的NoteEditText视图,并将其文本追加到前一个视图的文本中,以便将文本合并到一个视图中。最后,该方法将焦点设置在前一个视图中,并将光标移动到文本末尾。 public void onEditTextEnter(int index, String text) { /** @@ -710,6 +736,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteEditor.setVisibility(View.GONE); mEditTextList.setVisibility(View.VISIBLE); } +// switchToListMode(String text)方法用于切换到清单模式。该方法首先清除所有视图,然后将文本根据换行符分隔为多个条目,并将每个条目添加到mEditTextList中。同时,该方法会添加一个新的空条目,以便用户可以在列表末尾添加新的条目。最后,该方法会将焦点设置在最后一个条目上,并将编辑器视图隐藏,将列表视图显示。 private Spannable getHighlightQueryResult(String fullText, String userQuery) { SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); @@ -727,6 +754,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return spannable; } +// getHighlightQueryResult(String fullText, String userQuery)方法用于标记在搜索查询中匹配的文本。该方法将返回一个Spannable对象,其中查询匹配的文本会被高亮显示。 private View getListItem(String item, int index) { View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); @@ -758,6 +786,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit.setText(getHighlightQueryResult(item, mUserQuery)); return view; } +// getListItem(String item, int index)方法用于获取一个清单视图。该方法将从R.layout.note_edit_list_item文件中充气视图。在充气视图之后,该方法会将文本添加到NoteEditText视图中,并将复选框设置为选中或未选中状态。如果条目已选中,则文本将具有删除线。最后,该方法将返回该视图。 public void onTextChange(int index, boolean hasText) { if (index >= mEditTextList.getChildCount()) { @@ -770,6 +799,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); } } +// onTextChange(int index, boolean hasText)方法用于在清单视图中标记是否有文本。如果hasText为true,则将显示复选框;否则,将隐藏复选框。 public void onCheckListModeChanged(int oldMode, int newMode) { if (newMode == TextNote.MODE_CHECK_LIST) { @@ -784,6 +814,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteEditor.setVisibility(View.VISIBLE); } } +// onCheckListModeChanged(int oldMode, int newMode)方法用于在清单模式和文本编辑模式之间切换。如果新模式为清单模式,则将文本转换为清单视图;否则,将清单视图转换为文本编辑视图。 private boolean getWorkingText() { boolean hasChecked = false; @@ -807,6 +838,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return hasChecked; } +// getWorkingText()方法用于获取当前工作文本。如果当前模式为清单模式,则将所有条目合并为一个字符串,并添加检查框状态。否则,将返回当前编辑器文本。 private boolean saveNote() { getWorkingText(); diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java index 2afe2a8..a4179e7 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java @@ -84,11 +84,11 @@ public class NoteEditText extends EditText { public void setIndex(int index) { mIndex = index; - } + }//用于设置控件在父容器中的位置索引 public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; - } + }//用于设置文本变化的监听器 public NoteEditText(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.editTextStyle); @@ -116,7 +116,7 @@ public class NoteEditText extends EditText { int off = layout.getOffsetForHorizontal(line, x); Selection.setSelection(getText(), off); break; - } + }//实现了点击控件后,将光标移动到点击位置的功能 return super.onTouchEvent(event); } @@ -166,6 +166,7 @@ public class NoteEditText extends EditText { } return super.onKeyUp(keyCode, event); } +// onKeyDown和onKeyUp方法实现了按下和松开键盘按键时的响应。 @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { @@ -177,7 +178,7 @@ public class NoteEditText extends EditText { } } super.onFocusChanged(focused, direction, previouslyFocusedRect); - } + }//控件获得或失去焦点时触发,将焦点状态通知给监听器。 @Override protected void onCreateContextMenu(ContextMenu menu) { @@ -214,4 +215,5 @@ public class NoteEditText extends EditText { } super.onCreateContextMenu(menu); } +// 创建上下文菜单,当用户长按控件中的链接时,根据链接的协议类型创建不同的菜单项,点击菜单项后跳转到相应的链接。 } diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java index c00449e..4d980ad 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -70,7 +70,6 @@ import net.micode.notes.tool.DataUtils; import net.micode.notes.tool.ResourceParser; import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; import net.micode.notes.widget.NoteWidgetProvider_2x; -import net.micode.notes.widget.NoteWidgetProvider_3x; import net.micode.notes.widget.NoteWidgetProvider_4x; import java.io.BufferedReader; @@ -142,7 +141,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt setContentView(R.layout.note_list); initResources(); - /* + /** * Insert an introduction when user firstly use this application */ setAppInfoFromRawRes(); @@ -157,10 +156,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt super.onActivityResult(requestCode, resultCode, data); } } +// 这个方法重写了Activity类的onActivityResult()方法。当startActivityForResult()启动的活动结束时,它会被调用。它检查结果是否为RESULT_OK并且请求了REQUEST_CODE_OPEN_NODE或REQUEST_CODE_NEW_NODE。如果是,则通过调用changeCursor(null)更新笔记列表适配器。否则,它调用超类实现的onActivityResult()方法。 private void setAppInfoFromRawRes() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { + // 从raw资源中读取介绍文件 StringBuilder sb = new StringBuilder(); InputStream in = null; try { @@ -203,6 +204,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } } +// 这个方法从一个原始的资源文件中读取介绍文件,并将其内容添加到应用程序的SharedPreferences中。如果介绍文件尚未被添加到SharedPreferences中,它将被添加,并设置一个标志表示文件已被添加。在此之后,每次启动应用程序时,它将不再读取介绍文件。 @Override protected void onStart() { @@ -269,6 +271,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }); return true; } +// 这是Activity的onCreate()方法,它在创建活动时被调用。它设置了视图并调用了setAppInfoFromRawRes()和initNoteListView()方法以初始化应用程序。 private void updateMenu() { int selectedCount = mNotesListAdapter.getSelectedCount(); @@ -285,33 +288,33 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt item.setTitle(R.string.menu_select_all); } } - } + }//更新下拉菜单中的选项。该方法首先获取当前选中的笔记数量,然后格式化菜单标题,更新下拉菜单的标题,并更新菜单项的状态。 public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; - } + }//准备操作模式。该方法在操作模式即将被启动时调用,并返回一个布尔值,指示是否应该启动操作模式。 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // TODO Auto-generated method stub return false; - } + }//处理操作模式中的菜单项点击事件。该方法在用户点击操作模式中的菜单项时调用,并返回一个布尔值,指示是否已经处理了该事件。 public void onDestroyActionMode(ActionMode mode) { mNotesListAdapter.setChoiceMode(false); mNotesListView.setLongClickable(true); mAddNewNote.setVisibility(View.VISIBLE); - } + }//销毁操作模式。该方法在操作模式被销毁时调用,并将列表适配器的选择模式设置为false,将列表项的长按功能重新启用,并显示添加新笔记的按钮。 public void finishActionMode() { mActionMode.finish(); - } + }//结束操作模式。该方法结束操作模式。 public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { mNotesListAdapter.setCheckedItem(position, checked); updateMenu(); - } + }//当用户选中或取消选中一个列表项时调用。该方法更新适配器中对应列表项的选中状态,并调用updateMenu()方法更新下拉菜单中的选项。 public boolean onMenuItemClick(MenuItem item) { if (mNotesListAdapter.getSelectedCount() == 0) { @@ -345,6 +348,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } return true; } +// 处理下拉菜单中的菜单项点击事件。该方法在用户点击下拉菜单中的菜单项时调用,并根据菜单项的ID执行相应的操作。如果成功处理了菜单项,则返回true,否则返回false。如果没有选中任何笔记,则显示一个Toast提示用户需要先选择笔记。如果选择了“删除”菜单项,则弹出一个对话框,询问用户是否确定要删除所选笔记。如果选择了“移动”菜单项,则启动查询目标文件夹的操作。 } private class NewNoteOnTouchListener implements OnTouchListener { @@ -418,21 +422,27 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); } +// 后台查询处理程序,继承自AsyncQueryHandler private final class BackgroundQueryHandler extends AsyncQueryHandler { public BackgroundQueryHandler(ContentResolver contentResolver) { super(contentResolver); } +// 构造函数,调用父类AsyncQueryHandler的构造函数 + // 查询完成后的回调函数,根据token值进行不同的处理 @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { switch (token) { case FOLDER_NOTE_LIST_QUERY_TOKEN: + // 更新列表Adapter的Cursor mNotesListAdapter.changeCursor(cursor); break; case FOLDER_LIST_QUERY_TOKEN: if (cursor != null && cursor.getCount() > 0) { + // 显示文件夹列表菜单 showFolderListMenu(cursor); } else { + // 查询文件夹失败,输出错误信息 Log.e(TAG, "Query folder failed"); } break; @@ -442,35 +452,48 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + // 显示文件夹列表菜单 private void showFolderListMenu(Cursor cursor) { + // 创建AlertDialog.Builder AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); builder.setTitle(R.string.menu_title_select_folder); + // 创建文件夹列表的Adapter final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor); + // 设置Adapter和点击事件 builder.setAdapter(adapter, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + // 批量移动选中的笔记到指定文件夹 DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which)); + // 显示移动笔记的提示信息 Toast.makeText( NotesListActivity.this, getString(R.string.format_move_notes_to_folder, mNotesListAdapter.getSelectedCount(), adapter.getFolderName(NotesListActivity.this, which)), Toast.LENGTH_SHORT).show(); + // 结束ActionMode mModeCallBack.finishActionMode(); } }); + // 显示AlertDialog builder.show(); } + // 创建新笔记 private void createNewNote() { + // 创建Intent,跳转到NoteEditActivity Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_INSERT_OR_EDIT); intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); + // 启动ActivityForResult this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); } + // 批量删除选中的笔记 private void batchDelete() { + // 创建异步任务 new AsyncTask>() { protected HashSet doInBackground(Void... unused) { HashSet widgets = mNotesListAdapter.getSelectedWidget(); @@ -534,47 +557,52 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + // 打开笔记详情页 private void openNode(NoteItemData data) { Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_VIEW); - intent.putExtra(Intent.EXTRA_UID, data.getId()); - this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); + intent.putExtra(Intent.EXTRA_UID, data.getId());// 将笔记的id作为参数传递给NoteEditActivity + this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);// 启动NoteEditActivity,并等待返回结果 } + // 打开文件夹 private void openFolder(NoteItemData data) { - mCurrentFolderId = data.getId(); - startAsyncNotesListQuery(); - if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { - mState = ListEditState.CALL_RECORD_FOLDER; - mAddNewNote.setVisibility(View.GONE); + mCurrentFolderId = data.getId();// 将当前文件夹的id保存到成员变量mCurrentFolderId + startAsyncNotesListQuery();// 异步查询当前文件夹下的笔记列表 + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {// 如果打开的是CallRecord文件夹 + mState = ListEditState.CALL_RECORD_FOLDER;// 设置状态为CALL_RECORD_FOLDER + mAddNewNote.setVisibility(View.GONE);// 隐藏新建笔记按钮 } else { - mState = ListEditState.SUB_FOLDER; + mState = ListEditState.SUB_FOLDER;// 设置状态为SUB_FOLDER } - if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { - mTitleBar.setText(R.string.call_record_folder_name); + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {// 如果打开的是CallRecord文件夹 + mTitleBar.setText(R.string.call_record_folder_name);// 将标题栏文本设置为"通话录音" } else { - mTitleBar.setText(data.getSnippet()); + mTitleBar.setText(data.getSnippet());// 将标题栏文本设置为当前文件夹的名字 } - mTitleBar.setVisibility(View.VISIBLE); + mTitleBar.setVisibility(View.VISIBLE); // 显示标题栏 } + // 按钮点击事件 public void onClick(View v) { switch (v.getId()) { case R.id.btn_new_note: - createNewNote(); + createNewNote();// 创建新笔记 break; default: break; } } + // 显示软键盘 private void showSoftInput() { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (inputMethodManager != null) { - inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // 显示软键盘 } } + // 隐藏软键盘 private void hideSoftInput(View view) { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); @@ -663,7 +691,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } }); - } + }//用于显示一个对话框,让用户输入或修改一个文件夹的名称。 @Override public void onBackPressed() { @@ -688,6 +716,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt break; } } +// 重写返回键的行为,根据当前的状态执行不同的操作,如返回到上一级文件夹、返回到笔记列表、或者直接退出应用程序。 private void updateWidget(int appWidgetId, int appWidgetType) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); @@ -695,8 +724,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt intent.setClass(this, NoteWidgetProvider_2x.class); } else if (appWidgetType == Notes.TYPE_WIDGET_4X) { intent.setClass(this, NoteWidgetProvider_4x.class); - } else if (appWidgetType == Notes.TYPE_WIDGET_3X) { - intent.setClass(this, NoteWidgetProvider_3x.class); } else { Log.e(TAG, "Unspported widget type"); return; @@ -709,6 +736,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt sendBroadcast(intent); setResult(RESULT_OK, intent); } +// 更新小部件的方法,根据小部件的类型选择不同的小部件提供者,并发送广播更新小部件。 private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { @@ -720,6 +748,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } }; +// 长按文件夹时创建上下文菜单的监听器,菜单包括查看文件夹、删除文件夹和修改文件夹名称等选项。 @Override public void onContextMenuClosed(Menu menu) { @@ -728,6 +757,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } super.onContextMenuClosed(menu); } +// 上下文菜单关闭时的操作,将监听器设为null。 @Override public boolean onContextItemSelected(MenuItem item) { @@ -762,6 +792,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } +// 选择上下文菜单选项时的操作,根据所选选项执行不同的操作,如打开文件夹、删除文件夹或修改文件夹名称。 @Override public boolean onPrepareOptionsMenu(Menu menu) { @@ -780,6 +811,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } return true; } +// 准备选项菜单时的操作,根据当前的状态显示不同的菜单选项,如笔记列表、子文件夹或通话记录文件夹。 @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -820,6 +852,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } return true; } +// 选择选项菜单选项时的操作,根据所选选项执行不同的操作,如打开笔记列表、打开子文件夹或打开通话记录文件夹。 @Override public boolean onSearchRequested() { @@ -872,12 +905,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private boolean isSyncMode() { return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } +// ,表示当前是否处于同步模式。它通过调用 NotesPreferenceActivity.getSyncAccountName(this) 获取同步账户名,并检查它的长度是否大于 0 来确定是否启用同步模式。 private void startPreferenceActivity() { Activity from = getParent() != null ? getParent() : this; Intent intent = new Intent(from, NotesPreferenceActivity.class); from.startActivityIfNeeded(intent, -1); } +// 方法启动设置活动,它创建一个 Intent 对象并使用当前活动作为上下文调用 startActivityIfNeeded() 方法来启动设置活动。如果当前活动已经是设置活动的父级,则使用 getParent() 方法获取父级活动。 private class OnListItemClickListener implements OnItemClickListener { @@ -919,6 +954,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } +// OnListItemClickListener 是一个内部类,实现了 OnItemClickListener 接口。它覆盖了 onItemClick() 方法,在列表项被单击时执行一系列操作。首先,它检查当前是否处于选择模式。如果是,则根据列表项的类型执行不同的操作。如果不是,则根据当前状态执行不同的操作,如打开文件夹或笔记。 private void startQueryDestinationFolders() { String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?"; @@ -937,6 +973,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }, NoteColumns.MODIFIED_DATE + " DESC"); } +// 启动后台查询,以获取目标文件夹列表。它构建一个查询选择器,通过调用 mBackgroundQueryHandler.startQuery() 方法执行查询操作。查询的结果将被传递到 FoldersListAdapter 中进行处理。 public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { if (view instanceof NotesListItem) { @@ -954,4 +991,5 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } return false; } +// 在列表项被长按时执行。它首先获取当前长按的列表项,并将其类型存储在 mFocusNoteDataItem 中。如果类型为笔记且不在选择模式下,则启动上下文操作模式,并将当前列表项标记为已选中。如果类型为文件夹,则设置上下文菜单的创建监听器。 } diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java index 51c9cb9..18f72ef 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java @@ -53,7 +53,7 @@ public class NotesListAdapter extends CursorAdapter { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return new NotesListItem(context); - } + }//创建一个新的笔记列表项视图,即 NotesListItem。 @Override public void bindView(View view, Context context, Cursor cursor) { @@ -62,21 +62,21 @@ public class NotesListAdapter extends CursorAdapter { ((NotesListItem) view).bind(context, itemData, mChoiceMode, isSelectedItem(cursor.getPosition())); } - } + }//将笔记数据绑定到给定的笔记列表项视图中。 public void setCheckedItem(final int position, final boolean checked) { mSelectedIndex.put(position, checked); notifyDataSetChanged(); - } + }//设置给定位置的笔记是否被选中,并通知适配器数据已更改。 public boolean isInChoiceMode() { return mChoiceMode; - } + }//返回是否处于选择笔记的模式。 public void setChoiceMode(boolean mode) { mSelectedIndex.clear(); mChoiceMode = mode; - } + }//设置选择笔记的模式,并清空 mSelectedIndex。 public void selectAll(boolean checked) { Cursor cursor = getCursor(); @@ -87,7 +87,7 @@ public class NotesListAdapter extends CursorAdapter { } } } - } + }//选择所有笔记。 public HashSet getSelectedItemIds() { HashSet itemSet = new HashSet(); @@ -103,7 +103,8 @@ public class NotesListAdapter extends CursorAdapter { } return itemSet; - } + }//返回选定的笔记的 ID。 + public HashSet getSelectedWidget() { HashSet itemSet = new HashSet(); @@ -126,7 +127,7 @@ public class NotesListAdapter extends CursorAdapter { } } return itemSet; - } + }//返回选定的小部件信息。 public int getSelectedCount() { Collection values = mSelectedIndex.values(); @@ -141,31 +142,31 @@ public class NotesListAdapter extends CursorAdapter { } } return count; - } + }//返回选定笔记的数量。 public boolean isAllSelected() { int checkedCount = getSelectedCount(); return (checkedCount != 0 && checkedCount == mNotesCount); - } + }//返回是否已经选择了所有笔记。 public boolean isSelectedItem(final int position) { if (null == mSelectedIndex.get(position)) { return false; } return mSelectedIndex.get(position); - } + }//返回给定位置的笔记是否被选中。 @Override protected void onContentChanged() { super.onContentChanged(); calcNotesCount(); - } + }//当笔记数据发生变化时,重新计算笔记数量。 @Override public void changeCursor(Cursor cursor) { super.changeCursor(cursor); calcNotesCount(); - } + }//更改笔记数据游标时,重新计算笔记数量。 private void calcNotesCount() { mNotesCount = 0; @@ -180,5 +181,5 @@ public class NotesListAdapter extends CursorAdapter { return; } } - } + }//计算笔记数量。 } diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java index 1221e80..147c4ea 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java @@ -98,6 +98,7 @@ public class NotesListItem extends LinearLayout { setBackground(data); } + // 用于将数据绑定到视图的UI组件上,它接受一个NoteItemData对象,其中包含有关笔记项的信息,以及两个布尔标志:choiceMode和checked。 private void setBackground(NoteItemData data) { int id = data.getBgColorId(); diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java index 07c5f7e..ed4d6af 100644 --- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java +++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java @@ -86,7 +86,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { mOriAccounts = null; View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); getListView().addHeaderView(header, null, true); - } + }//当创建Activity时调用。在此方法中,ActionBar的返回按钮启用,加载应用程序的偏好设置,注册广播接收器,添加一个标题视图。 @Override protected void onResume() { @@ -114,7 +114,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { } refreshUI(); - } + }//当Activity从暂停状态恢复时调用。在此方法中,检查用户是否已添加了新帐户,如果是,则需要自动设置同步帐户。 @Override protected void onDestroy() { @@ -122,7 +122,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { unregisterReceiver(mReceiver); } super.onDestroy(); - } + }//当Activity被销毁时调用。在此方法中,注销广播接收器。 private void loadAccountPreference() { mAccountCategory.removeAll(); @@ -152,7 +152,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { }); mAccountCategory.addPreference(accountPref); - } + }//加载应用程序的帐户偏好设置,包括标题、摘要和单击事件监听器。 private void loadSyncButton() { Button syncButton = (Button) findViewById(R.id.preference_sync_button); @@ -191,12 +191,12 @@ public class NotesPreferenceActivity extends PreferenceActivity { lastSyncTimeView.setVisibility(View.GONE); } } - } + }//加载同步按钮和上次同步时间文本视图,并设置相应的单击事件监听器。 private void refreshUI() { loadAccountPreference(); loadSyncButton(); - } + }//刷新用户界面,加载帐户偏好设置和同步按钮。 private void showSelectAccountAlertDialog() { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); @@ -252,7 +252,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { dialog.dismiss(); } }); - } + }//弹出一个对话框,提示用户选择一个帐户进行同步。 private void showChangeAccountConfirmAlertDialog() { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); @@ -384,5 +384,5 @@ public class NotesPreferenceActivity extends PreferenceActivity { default: return false; } - } + }//当用户选择同步帐户时调用。在此方法中,更新同步按钮的文本视图,并启用同步按钮。 }