diff --git a/src/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java index 815f2be..fa4344a 100644 --- a/src/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java @@ -40,103 +40,115 @@ import net.micode.notes.tool.DataUtils; import java.io.IOException; -public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { +public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener //AlarmAlertActivity类实现了OnClickListener, OnDismissListener两个接口,OnClickListener接口用于处理点击事件,当用户点击了界面上的某个视图时,会调用相应的点击事件处理方法。在AlarmAlertActivity中,通过实现OnClickListener接口,可以监听用户对界面上的按钮或其他可点击视图的点击事件,并根据需要进行相应的处理。OnDismissListener接口用于处理对话框消失事件。当一个对话框被关闭或隐藏时,会调用相应的消失事件处理方法。在AlarmAlertActivity中,通过实现OnDismissListener接口,可以监听闹钟提醒对话框的消失事件,并在对话框消失后执行相应的操作。通过实现这两个接口,AlarmAlertActivity可以监听界面上的点击事件和闹钟提醒对话框的消失事件,并在相应事件发生时执行相应的逻辑操作。 +{ private long mNoteId; //文本在数据库存储中的ID号 - private String mSnippet; - private static final int SNIPPET_PREW_MAX_LEN = 60; - MediaPlayer mPlayer; + private String mSnippet;//闹钟提示时出现的文本片段。 + private static final int SNIPPET_PREW_MAX_LEN = 60;// 文本片段预览的最大长度 + MediaPlayer mPlayer;// 媒体播放器 @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(Bundle savedInstanceState) //当一个Activity被创建时系统会调用该的onCreate()方法,在onCreate()方法的参数savedInstanceState是一个Bundle对象,用于保存Activity的状态。当Activity因为某种原因(例如屏幕旋转、内存不足等)被销毁时,系统会将Activity的状态保存在savedInstanceState中。当Activity重新创建时,系统会将savedInstanceState传递给onCreate()方法,以便恢复之前保存的状态。 + { super.onCreate(savedInstanceState); - requestWindowFeature(Window.FEATURE_NO_TITLE); + requestWindowFeature(Window.FEATURE_NO_TITLE);// 隐藏标题栏 final Window win = getWindow(); - win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);// 在锁屏状态下显示窗口 - if (!isScreenOn()) { - win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON - | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON - | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON - | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); - } + if (!isScreenOn()) // 如果屏处于关闭状态,设置一些窗口标志来保持屏幕亮起 + { + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON//保持屏幕亮起的标志,表示在该窗口下,保持屏幕处于亮屏状态。 + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON//点亮屏幕的标志,表示在该窗口下,当窗口显示时,点亮屏幕。 + + | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON//在屏幕亮起时允许锁定的标志,表示在该窗口下,允许用户在屏幕亮起时锁定屏幕。 + + | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);//布局插入装饰的标志,表示在该窗口下,窗口的布局可以延伸到系统装饰的边缘。 + + }//用于在创建Activity时设置窗口标志,以确保在显示闹钟提醒界面时,屏幕保持亮起,并且在锁屏状态下仍然显示窗口。这样可以确保用户能够及时看到闹钟提醒的内容。 Intent intent = getIntent(); try { + // 从传递的Intent中获取文本的ID号,并获取对应的文本片段 mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); + // 如果文本片段长度超过预设的最大长度,截取一部分,并添加提示信息 mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) : mSnippet; } catch (IllegalArgumentException e) { - e.printStackTrace(); - return; + e.printStackTrace();// 打印异常信息 + return;// 结束方法的执行 } - mPlayer = new MediaPlayer(); - if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { - showActionDialog(); - playAlarmSound(); + mPlayer = new MediaPlayer(); // 创建一个媒体播放器对象 + if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) // 如果文本在数据库中可见 + { + showActionDialog();// 显示操作对话框 + playAlarmSound(); // 播放闹钟声音 } else { - finish(); + finish();// 结束当前Activity } } - + /** + * 判断屏幕是否处于亮状态。 + * @return true表示屏幕处于亮屏状态,false表示屏幕处于关闭状态 + */ private boolean isScreenOn() { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - return pm.isScreenOn(); + return pm.isScreenOn(); // 返回屏幕是否处于亮屏状态 } - + /** + * 播放闹钟音。 + */ private void playAlarmSound() { - Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); - + Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);// 获取闹钟铃声的URI + //这里的流都是音频流 int silentModeStreams = Settings.System.getInt(getContentResolver(), - Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); + Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);// 获取当前静音模式下影响铃声的流 - if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { + if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) // 如果静音模式下影响铃声的流中包含闹钟铃声流,设置媒体播放器的音频流为静音模式下影响铃声的流 + { mPlayer.setAudioStreamType(silentModeStreams); - } else { + } else// 否则,设置媒体播放器的音频流为闹钟铃声流 + { mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); } try { - mPlayer.setDataSource(this, url); - mPlayer.prepare(); - mPlayer.setLooping(true); - mPlayer.start(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block + mPlayer.setDataSource(this, url); // 设置媒体放器的数据源为闹钟铃声的URI + mPlayer.prepare(); // 准备异步播放 + mPlayer.setLooping(true); // 设置循环播放 + mPlayer.start(); // 开始播放 + } catch (IllegalArgumentException e) { // 处理参数异常 e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block + } catch (SecurityException e) { // 处理安全异常 e.printStackTrace(); - } catch (IllegalStateException e) { - // TODO Auto-generated catch block + } catch (IllegalStateException e) { // 处理状态异常 e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block + } catch (IOException e) { // 处理IO异常 e.printStackTrace(); } } private void showActionDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(this); - dialog.setTitle(R.string.app_name); - dialog.setMessage(mSnippet); - dialog.setPositiveButton(R.string.notealert_ok, this); - if (isScreenOn()) { - dialog.setNegativeButton(R.string.notealert_enter, this); + dialog.setTitle(R.string.app_name); // 设置对话框标题 + dialog.setMessage(mSnippet); // 设置对话框消息内容 + dialog.setPositiveButton(R.string.notealert_ok, this); // 设置对话框的确定按钮和点击事件 + if (isScreenOn()) { // 判断屏幕是否亮屏 + dialog.setNegativeButton(R.string.notealert_enter, this); // 设置对话框的取消按钮和点击事件 } - dialog.show().setOnDismissListener(this); + dialog.show().setOnDismissListener(this); // 显示对话框,并设置对话框消失时的监听器 } public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_NEGATIVE: - Intent intent = new Intent(this, NoteEditActivity.class); - intent.setAction(Intent.ACTION_VIEW); - intent.putExtra(Intent.EXTRA_UID, mNoteId); - startActivity(intent); + Intent intent = new Intent(this, NoteEditActivity.class); // 创建一个Intent对象,跳转到NoteEditActivity + intent.setAction(Intent.ACTION_VIEW); // 设置Intent的操作为查看操作 + intent.putExtra(Intent.EXTRA_UID, mNoteId); // 设置Intent的额外数据 + startActivity(intent); // 启动Activity break; default: break; @@ -144,15 +156,14 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } public void onDismiss(DialogInterface dialog) { - stopAlarmSound(); - finish(); + stopAlarmSound(); // 停止播放铃声 + finish(); // 结束当前Activity } - private void stopAlarmSound() { if (mPlayer != null) { - mPlayer.stop(); - mPlayer.release(); - mPlayer = null; + mPlayer.stop(); // 停止播放 + mPlayer.release(); // 释放资源 + mPlayer = null; // 置空。 } } } diff --git a/src/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java index f221202..d587094 100644 --- a/src/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java +++ b/src/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java @@ -30,36 +30,43 @@ import net.micode.notes.data.Notes.NoteColumns; public class AlarmInitReceiver extends BroadcastReceiver { - private static final String [] PROJECTION = new String [] { - NoteColumns.ID, - NoteColumns.ALERTED_DATE + // 查询备忘录的投影 + private static final String[] PROJECTION = new String[] { + NoteColumns.ID, + NoteColumns.ALERTED_DATE }; - private static final int COLUMN_ID = 0; - private static final int COLUMN_ALERTED_DATE = 1; - + // 列索引 + private static final int COLUMN_ID = 0; + private static final int COLUMN_ALERTED_DATE = 1; @Override public void onReceive(Context context, Intent intent) { + // 获取当前时间 long currentDate = System.currentTimeMillis(); + // 查询所有需要提醒的备忘录 Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, PROJECTION, NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, - new String[] { String.valueOf(currentDate) }, + new String[]{String.valueOf(currentDate)}, null); if (c != null) { if (c.moveToFirst()) { do { + // 获取提醒时间和备忘录的ID long alertDate = c.getLong(COLUMN_ALERTED_DATE); + long noteId = c.getLong(COLUMN_ID); + // 创建一个发送广播的Intent,并设置数据为备忘录的URI Intent sender = new Intent(context, AlarmReceiver.class); - sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); + sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId)); + // 创建一个PendingIntent,用于发送广播 PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); - AlarmManager alermManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); + // 获取AlarmManager实例,并设置提醒时间和发送广播的PendingIntent + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + alarmManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); } while (c.moveToNext()); } c.close(); } } -} +} \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java b/src/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java index 54e503b..fd8af6f 100644 --- a/src/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java +++ b/src/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java @@ -23,8 +23,11 @@ import android.content.Intent; public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { + // 创建一个新的Intent对象,将目标Activity设置为AlarmAlertActivity intent.setClass(context, AlarmAlertActivity.class); + // 添加标志FLAG_ACTIVITY_NEW_TASK,以确保启动Activity时具有新的任务栈 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // 启动目标Activity context.startActivity(intent); } -} +} \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/DateTimePicker.java b/src/Notes-master/src/net/micode/notes/ui/DateTimePicker.java index 496b0cd..f41a158 100644 --- a/src/Notes-master/src/net/micode/notes/ui/DateTimePicker.java +++ b/src/Notes-master/src/net/micode/notes/ui/DateTimePicker.java @@ -30,45 +30,60 @@ import android.widget.NumberPicker; public class DateTimePicker extends FrameLayout { + // 默认启用状态 private static final boolean DEFAULT_ENABLE_STATE = true; + // 一半天的小时数 private static final int HOURS_IN_HALF_DAY = 12; + // 一天的小时数 private static final int HOURS_IN_ALL_DAY = 24; + // 一周的天数 private static final int DAYS_IN_ALL_WEEK = 7; + // 日期选择器的最小值 private static final int DATE_SPINNER_MIN_VAL = 0; + // 日期选择器的最大值 private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1; + // 24小时制时钟的小时选择器的最小值 private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0; + // 24小时制时钟的小时选择器的最大值 private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23; + // 12小时制时钟的小时选择器的最小值 private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1; + // 12小时制时钟的小时选择器的最大值 private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12; + // 分钟选择器的最小值 private static final int MINUT_SPINNER_MIN_VAL = 0; + // 分钟选择器的最大值 private static final int MINUT_SPINNER_MAX_VAL = 59; + // 上午/下午选择器的最小值 private static final int AMPM_SPINNER_MIN_VAL = 0; + // 上午/下午选择器的最大值 private static final int AMPM_SPINNER_MAX_VAL = 1; + private final NumberPicker mDateSpinner; // 日期选择器控件 + private final NumberPicker mHourSpinner; // 小时选择器控件 + private final NumberPicker mMinuteSpinner; // 分钟选择器控件 + private final NumberPicker mAmPmSpinner; // 上午/下午选择器控件 + private Calendar mDate; // 当前日期时间 - private final NumberPicker mDateSpinner; - private final NumberPicker mHourSpinner; - private final NumberPicker mMinuteSpinner; - private final NumberPicker mAmPmSpinner; - private Calendar mDate; + private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; // 一周的日期显示值 - private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; + private boolean mIsAm; // 当前是否为上午 - private boolean mIsAm; + private boolean mIs24HourView; // 是否为24小时制显示 - private boolean mIs24HourView; + private boolean mIsEnabled = DEFAULT_ENABLE_STATE; // 是否启用选择器的状态,默认为启用 - private boolean mIsEnabled = DEFAULT_ENABLE_STATE; - - private boolean mInitialising; - - private OnDateTimeChangedListener mOnDateTimeChangedListener; + private boolean mInitialising; // 是否正在初始化 + private OnDateTimeChangedListener mOnDateTimeChangedListener; // 日期时间变化监听器 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(); } }; @@ -79,6 +94,7 @@ public class DateTimePicker extends FrameLayout { boolean isDateChanged = false; Calendar cal = Calendar.getInstance(); if (!mIs24HourView) { + // 处理上午/下午切换时的日期变化 if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); @@ -88,12 +104,14 @@ public class DateTimePicker extends FrameLayout { cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } + // 处理上午/下午切换时的上午/下午选择器更新 if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { mIsAm = !mIsAm; updateAmPmControl(); } } else { + // 处理24小时制下的日期变化 if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); @@ -104,9 +122,11 @@ public class DateTimePicker extends FrameLayout { isDateChanged = true; } } + // 更新小时,并触发日期时间变化监听器 int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); mDate.set(Calendar.HOUR_OF_DAY, newHour); onDateTimeChanged(); + // 如果日期发生了变化,更新年、月、日 if (isDateChanged) { setCurrentYear(cal.get(Calendar.YEAR)); setCurrentMonth(cal.get(Calendar.MONTH)); @@ -114,143 +134,169 @@ public class DateTimePicker extends FrameLayout { } } }; - private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - int minValue = mMinuteSpinner.getMinValue(); - int maxValue = mMinuteSpinner.getMaxValue(); - int offset = 0; - if (oldVal == maxValue && newVal == minValue) { - offset += 1; - } else if (oldVal == minValue && newVal == maxValue) { - offset -= 1; + int minValue = mMinuteSpinner.getMinValue(); // 获取分钟选择器的最小值 + int maxValue = mMinuteSpinner.getMaxValue(); // 获取分钟选择器的最大值 + int offset = 0; // 偏移量,用于处理分钟的循环 + if (oldVal == maxValue && newVal == minValue) { // 判断是否从最大值切换到最小值 + offset += 1; // 如果是,则偏移量加1 + } else if (oldVal == minValue && newVal == maxValue) { // 判断是否从最小值切换到最大值 + offset -= 1; // 如果是,则偏移量减1 } - if (offset != 0) { - mDate.add(Calendar.HOUR_OF_DAY, offset); - mHourSpinner.setValue(getCurrentHour()); - updateDateControl(); - int newHour = getCurrentHourOfDay(); - if (newHour >= HOURS_IN_HALF_DAY) { - mIsAm = false; - updateAmPmControl(); + if (offset != 0) { // 如果偏移量不为0,表示分钟发生了循环 + mDate.add(Calendar.HOUR_OF_DAY, offset); // 更新小时的值 + mHourSpinner.setValue(getCurrentHour()); // 更新小时选择器的值 + updateDateControl(); // 更新日期选择器控件 + int newHour = getCurrentHourOfDay(); // 获取当前小时 + if (newHour >= HOURS_IN_HALF_DAY) { // 如果当前小时大于等于一半天的小时数 + mIsAm = false; // 设置为下午 + updateAmPmControl(); // 更新上午/下午选择器控件 } else { - mIsAm = true; - updateAmPmControl(); + mIsAm = true; // 设置为上午 + updateAmPmControl(); // 更新上午/下午选择器控件 } } - mDate.set(Calendar.MINUTE, newVal); - onDateTimeChanged(); + mDate.set(Calendar.MINUTE, newVal); // 更新分钟的值 + onDateTimeChanged(); // 触发日期时间变化监听器 } }; private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - mIsAm = !mIsAm; - if (mIsAm) { - mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); - } else { - mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY); + mIsAm = !mIsAm; // 切换上午/下午的状态 + if (mIsAm) { // 如果切换为上午 + mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); // 将当前时间减去半天的小时数 + } else { // 如果切换为下午 + mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY); // 将当前时间加上半天的小时数 } - updateAmPmControl(); - onDateTimeChanged(); + updateAmPmControl(); // 更新上午/下午选择器控件 + onDateTimeChanged(); // 触发日期时间变化监听器 } }; - public interface OnDateTimeChangedListener { - void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute); + /** + * 当日期时间发生变化时调用 + * + * @param view 当前的 DateTimePicker 对象 + * @param year 年份 + * @param month 月份,范围为 0-11,0 表示一月 + * @param dayOfMonth 日期 + * @param hourOfDay 小时,根据是否为 24 小时制可能为 0-23 或 1-12 + * @param minute 分钟 + */ + void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute); } + /** + * 构造方法,创建一个 DateTimePicker 对象,并将当前时间设置为系统当前时间 + * + * @param context 上下文环境 + */ public DateTimePicker(Context context) { this(context, System.currentTimeMillis()); } + /** + * 构造方法,创建一个 DateTimePicker 对象,并设置指定的日期时间和小时制 + * + * @param context 上下文环境 + * @param date 指定的日期时间,以毫秒为单位 + * @param is24HourView 是否为 24 小时制显示 + */ public DateTimePicker(Context context, long date) { this(context, date, DateFormat.is24HourFormat(context)); } 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); - - mDateSpinner = (NumberPicker) findViewById(R.id.date); - mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); - mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); - mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); - - mHourSpinner = (NumberPicker) findViewById(R.id.hour); - mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); - mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); - mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); - mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); - mMinuteSpinner.setOnLongPressUpdateInterval(100); - mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); - - String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); - mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); - mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); - mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); - mAmPmSpinner.setDisplayedValues(stringsForAmPm); - mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); - - // update controls to initial state - updateDateControl(); - updateHourControl(); - updateAmPmControl(); - - set24HourView(is24HourView); - - // set to current time - setCurrentDate(date); - - setEnabled(isEnabled()); - - // set the content descriptions - mInitialising = false; + super(context); // 调用父类的构造方法 + mDate = Calendar.getInstance(); // 获取当前时间的日历对象 + mInitialising = true; // 表示正在初始化 + mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; // 根据当前小时判断是否为上午 + inflate(context, R.layout.datetime_picker, this); // 将布局文件实例化为视图并添加到当前视图 + + mDateSpinner = (NumberPicker) findViewById(R.id.date); // 获取日期选择器视图 + mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); // 设置日期选择器的最小值 + mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); // 设置日期选择器的最大值 + mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); // 设置日期选择器值变化的监听器 + + mHourSpinner = (NumberPicker) findViewById(R.id.hour); // 获取小时选择器视图 + mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); // 设置小时选择器值变化的监听器 + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); // 获取分钟选择器视图 + mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); // 设置分钟选择器的最小值 + mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); // 设置分钟选择器的最大值 + mMinuteSpinner.setOnLongPressUpdateInterval(100); // 设置长按更新间隔 + mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); // 设置分钟选择器值变化的监听器 + + String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); // 获取上午/下午的字符串数组 + mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); // 获取上午/下午选择器视图 + mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); // 设置上午/下午选择器的最小值 + mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); // 设置上午/下午选择器的最大值 + mAmPmSpinner.setDisplayedValues(stringsForAmPm); // 设置上午/下午选择器的显示值 + mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); // 设置上午/下午选择器值变化的监听器 + + updateDateControl(); // 更新日期选择器控件 + updateHourControl(); // 更新小时选择器控件 + updateAmPmControl(); // 更新上午/下午选择器控件 + + set24HourView(is24HourView); // 设置小时制显示 + + setCurrentDate(date); // 设置当前日期时间 + + setEnabled(isEnabled()); // 设置是否可用 + + mInitialising = false; // 初始化完成 } + /** + * 设置控件是否可用 + * + * @param enabled 是否可用 + */ @Override public void setEnabled(boolean enabled) { if (mIsEnabled == enabled) { return; } - super.setEnabled(enabled); - mDateSpinner.setEnabled(enabled); - mMinuteSpinner.setEnabled(enabled); - mHourSpinner.setEnabled(enabled); - mAmPmSpinner.setEnabled(enabled); - mIsEnabled = enabled; + super.setEnabled(enabled); // 调用父类方法设置控件可用状态 + mDateSpinner.setEnabled(enabled); // 设置日期选择器是否可用 + mMinuteSpinner.setEnabled(enabled); // 设置分钟选择器是否可用 + mHourSpinner.setEnabled(enabled); // 设置小时选择器是否可用 + mAmPmSpinner.setEnabled(enabled); // 设置上午/下午选择器是否可用 + mIsEnabled = enabled; // 更新控件是否可用状态 } + /** + * 判断控件是否可用 + * + * @return 控件是否可用 + */ @Override public boolean isEnabled() { return mIsEnabled; } /** - * Get the current date in millis + * 获取当前日期的毫秒值 * - * @return the current date in millis + * @return 当前日期的毫秒值 */ public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); } /** - * Set the current date + * 设置当前日期 * - * @param date The current date in millis + * @param date The current date in millis 当前日期的毫秒值 */ public void setCurrentDate(long date) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(date); - setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); + mDate.setTimeInMillis(date); // 将指定的日期毫秒值设置到日期对象中 + updateDateControl(); // 更新日期选择器控件 + updateHourControl(); // 更新小时选择器控件 + updateAmPmControl(); // 更新上午/下午选择器控件 } /** @@ -262,13 +308,12 @@ public class DateTimePicker extends FrameLayout { * @param hourOfDay The current hourOfDay * @param minute The current minute */ - public void setCurrentDate(int year, int month, - int dayOfMonth, int hourOfDay, int minute) { - setCurrentYear(year); - setCurrentMonth(month); - setCurrentDay(dayOfMonth); - setCurrentHour(hourOfDay); - setCurrentMinute(minute); + public void setCurrentDate(int year, int month, int dayOfMonth, int hourOfDay, int minute) { + setCurrentYear(year); // 设置当前年份 + setCurrentMonth(month); // 设置当前月份 + setCurrentDay(dayOfMonth); // 设置当前日期 + setCurrentHour(hourOfDay); // 设置当前小时 + setCurrentMinute(minute); // 设置当前分钟 } /** @@ -289,9 +334,9 @@ public class DateTimePicker extends FrameLayout { if (!mInitialising && year == getCurrentYear()) { return; } - mDate.set(Calendar.YEAR, year); - updateDateControl(); - onDateTimeChanged(); + mDate.set(Calendar.YEAR, year); // 设置日期对象的年份 + updateDateControl(); // 更新日期选择器控件 + onDateTimeChanged(); // 通知日期时间改变 } /** @@ -300,180 +345,192 @@ public class DateTimePicker extends FrameLayout { * @return The current month in the year */ public int getCurrentMonth() { - return mDate.get(Calendar.MONTH); + return mDate.get(Calendar.MONTH); // 获取日期对象的月份字段 } + /** - * Set current month in the year + * 设置当前月份 * - * @param month The month in the year + * @param month 月份(从0开始,0代表一月) */ public void setCurrentMonth(int month) { if (!mInitialising && month == getCurrentMonth()) { return; } - mDate.set(Calendar.MONTH, month); - updateDateControl(); - onDateTimeChanged(); + mDate.set(Calendar.MONTH, month); // 设置日期对象的月份 + updateDateControl(); // 更新日期选择器控件 + onDateTimeChanged(); // 通知日期时间改变 } /** - * Get current day of the month + * 获取当前日期的天数 * - * @return The day of the month + * @return 当前日期的天数 */ public int getCurrentDay() { - return mDate.get(Calendar.DAY_OF_MONTH); + return mDate.get(Calendar.DAY_OF_MONTH); // 获取日期对象的天数字段 } /** - * Set current day of the month + * 设置当前日期的天数 * - * @param dayOfMonth The day of the month + * @param dayOfMonth 日期的天数 */ public void setCurrentDay(int dayOfMonth) { if (!mInitialising && dayOfMonth == getCurrentDay()) { return; } - mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); - updateDateControl(); - onDateTimeChanged(); + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); // 设置日期对象的天数字段 + updateDateControl(); // 更新日期选择器控件 + onDateTimeChanged(); // 通知日期时间改变 } /** - * Get current hour in 24 hour mode, in the range (0~23) - * @return The current hour in 24 hour mode + * 获取当前的小时(24小时制),范围为0~23 + * + * @return 当前的小时(24小时制) */ public int getCurrentHourOfDay() { - return mDate.get(Calendar.HOUR_OF_DAY); + return mDate.get(Calendar.HOUR_OF_DAY); // 获取日期对象的小时字段(24小时制) } + /** + * 获取当前的小时 + * + * @return 当前的小时 + */ private int getCurrentHour() { - if (mIs24HourView){ - return getCurrentHourOfDay(); - } else { - int hour = getCurrentHourOfDay(); - if (hour > HOURS_IN_HALF_DAY) { - return hour - HOURS_IN_HALF_DAY; - } else { - return hour == 0 ? HOURS_IN_HALF_DAY : hour; + if (mIs24HourView) { // 如果是24小时制 + return getCurrentHourOfDay(); // 直接获取当前的小时 + } else { // 如果是12小时制 + int hour = getCurrentHourOfDay(); // 获取当前的小时 + if (hour > HOURS_IN_HALF_DAY) { // 如果大于12小时 + return hour - HOURS_IN_HALF_DAY; // 返回减去12小时的小时数 + } else { // 如果小于等于12小时 + return hour == 0 ? HOURS_IN_HALF_DAY : hour; // 如果小时为0,则返回12小时,否则返回当前的小时 } } } /** - * Set current hour in 24 hour mode, in the range (0~23) + * 设置当前小时(24小时制),范围为0~23 * - * @param hourOfDay + * @param hourOfDay 小时(24小时制) */ public void setCurrentHour(int hourOfDay) { if (!mInitialising && hourOfDay == getCurrentHourOfDay()) { return; } - mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); - if (!mIs24HourView) { - if (hourOfDay >= HOURS_IN_HALF_DAY) { - mIsAm = false; + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); // 设置日期对象的小时字段(24小时制) + if (!mIs24HourView) { // 如果是12小时制 + if (hourOfDay >= HOURS_IN_HALF_DAY) { // 如果小时大于等于12 + mIsAm = false; // 设置为下午 if (hourOfDay > HOURS_IN_HALF_DAY) { - hourOfDay -= HOURS_IN_HALF_DAY; + hourOfDay -= HOURS_IN_HALF_DAY; // 减去12小时 } - } else { - mIsAm = true; + } else { // 如果小时小于12 + mIsAm = true; // 设置为上午 if (hourOfDay == 0) { - hourOfDay = HOURS_IN_HALF_DAY; + hourOfDay = HOURS_IN_HALF_DAY; // 如果小时为0,则设置为12小时 } } - updateAmPmControl(); + updateAmPmControl(); // 更新上午/下午选择控件 } - mHourSpinner.setValue(hourOfDay); - onDateTimeChanged(); + mHourSpinner.setValue(hourOfDay); // 设置小时选择控件的值 + onDateTimeChanged(); // 通知日期时间改变 } /** - * Get currentMinute + * 获取当前的分钟 * - * @return The Current Minute + * @return 当前的分钟 */ public int getCurrentMinute() { - return mDate.get(Calendar.MINUTE); + return mDate.get(Calendar.MINUTE); // 获取日期对象的分钟字段 } /** - * Set current minute + * 设置当前的分钟 + * + * @param minute 分钟 */ public void setCurrentMinute(int minute) { if (!mInitialising && minute == getCurrentMinute()) { return; } - mMinuteSpinner.setValue(minute); - mDate.set(Calendar.MINUTE, minute); - onDateTimeChanged(); + mMinuteSpinner.setValue(minute); // 设置分钟选择控件的值 + mDate.set(Calendar.MINUTE, minute); // 设置日期对象的分钟字段 + onDateTimeChanged(); // 通知日期时间改变 } /** - * @return true if this is in 24 hour view else false. + * 判断是否为24小时制 + * + * @return 如果为24小时制返回true,否则返回false */ - public boolean is24HourView () { - return mIs24HourView; + public boolean is24HourView() { + return mIs24HourView; // 返回是否为24小时制的标志位 } /** - * Set whether in 24 hour or AM/PM mode. + * 设置是否为24小时制或上午/下午制 * - * @param is24HourView True for 24 hour mode. False for AM/PM mode. + * @param is24HourView true表示为24小时制,false表示为上午/下午制 */ public void set24HourView(boolean is24HourView) { if (mIs24HourView == is24HourView) { return; } - mIs24HourView = is24HourView; - mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); - int hour = getCurrentHourOfDay(); - updateHourControl(); - setCurrentHour(hour); - updateAmPmControl(); + mIs24HourView = is24HourView; // 设置是否为24小时制的标志位 + mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); // 根据是否为24小时制设置上午/下午选择控件的可见性 + int hour = getCurrentHourOfDay(); // 获取当前的小时(24小时制) + updateHourControl(); // 更新小时选择控件 + setCurrentHour(hour); // 设置当前的小时 + updateAmPmControl(); // 更新上午/下午选择控件 } - private void updateDateControl() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(mDate.getTimeInMillis()); - cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); - mDateSpinner.setDisplayedValues(null); + Calendar cal = Calendar.getInstance(); // 创建一个新的Calendar对象 + cal.setTimeInMillis(mDate.getTimeInMillis()); // 将mDate的时间设置给新的Calendar对象 + cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); // 将日期向前移动DAYS_IN_ALL_WEEK / 2 + 1天 + + mDateSpinner.setDisplayedValues(null); // 清空日期选择控件的显示值 for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) { - cal.add(Calendar.DAY_OF_YEAR, 1); - mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); + cal.add(Calendar.DAY_OF_YEAR, 1); // 将日期加上1天 + mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); // 将日期格式化为"MM.dd EEEE"的字符串格式,并存储到mDateDisplayValues数组中 } - mDateSpinner.setDisplayedValues(mDateDisplayValues); - mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); - mDateSpinner.invalidate(); - } + mDateSpinner.setDisplayedValues(mDateDisplayValues); // 设置日期选择控件的显示值为mDateDisplayValues数组 + mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); // 设置日期选择控件的当前值为DAYS_IN_ALL_WEEK / 2 + mDateSpinner.invalidate(); // 使日期选择控件无效,以便重绘 + } private void updateAmPmControl() { if (mIs24HourView) { - mAmPmSpinner.setVisibility(View.GONE); + mAmPmSpinner.setVisibility(View.GONE); // 如果是24小时制,隐藏上午/下午选择控件 } else { - int index = mIsAm ? Calendar.AM : Calendar.PM; - mAmPmSpinner.setValue(index); - mAmPmSpinner.setVisibility(View.VISIBLE); + int index = mIsAm ? Calendar.AM : Calendar.PM; // 根据当前上午/下午的标志位确定要显示的上午/下午选项 + mAmPmSpinner.setValue(index); // 设置上午/下午选择控件的值为对应的索引 + mAmPmSpinner.setVisibility(View.VISIBLE); // 显示上午/下午选择控件 } } private void updateHourControl() { if (mIs24HourView) { - mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); - mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); // 设置小时选择控件的最小值为24小时制的最小值 + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); // 设置小时选择控件的最大值为24小时制的最大值 } else { - mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); - mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); // 设置小时选择控件的最小值为12小时制的最小值 + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); // 设置小时选择控件的最大值为12小时制的最大值 } } /** - * Set the callback that indicates the 'Set' button has been pressed. - * @param callback the callback, if null will do nothing + * 设置“设置”按钮按下时的回调 + * + * @param callback 回调接口,如果为null则不执行任何操作 */ public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { - mOnDateTimeChangedListener = callback; + mOnDateTimeChangedListener = callback; // 设置回调接口 } private void onDateTimeChanged() { @@ -482,4 +539,3 @@ public class DateTimePicker extends FrameLayout { getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); } } -} diff --git a/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..b99ed29 100644 --- a/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -31,37 +31,38 @@ import android.text.format.DateUtils; public class DateTimePickerDialog extends AlertDialog implements OnClickListener { - private Calendar mDate = Calendar.getInstance(); - private boolean mIs24HourView; - private OnDateTimeSetListener mOnDateTimeSetListener; - private DateTimePicker mDateTimePicker; + private Calendar mDate = Calendar.getInstance(); // 创建一个Calendar对象,并初始化为当前日期时间 + private boolean mIs24HourView; // 是否为24小时制 + private OnDateTimeSetListener mOnDateTimeSetListener; // 日期时间设置回调接口 + private DateTimePicker mDateTimePicker; // 日期时间选择器控件 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } public DateTimePickerDialog(Context context, long date) { - super(context); - mDateTimePicker = new DateTimePicker(context); - setView(mDateTimePicker); + super(context); // 调用父类的构造方法 + mDateTimePicker = new DateTimePicker(context); // 创建一个DateTimePicker对象 + setView(mDateTimePicker); // 设置对话框的视图为DateTimePicker对象 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.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()); + int dayOfMonth, int hourOfDay, int minute) { + 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.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()); + + mDate.setTimeInMillis(date); // 将传入的日期设置给日期对象mDate + mDate.set(Calendar.SECOND, 0); // 将日期对象的秒设置为0 + mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); // 将日期对象的时间设置给DateTimePicker控件 + setButton(context.getString(R.string.datetime_dialog_ok), this); // 设置对话框的“确定”按钮,并设置点击监听器为当前对象 + setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); // 设置对话框的“取消”按钮,不设置点击监听器 + set24HourView(DateFormat.is24HourFormat(this.getContext())); // 根据系统设置判断是否为24小时制,并设置给日期时间选择器控件 + updateTitle(mDate.getTimeInMillis()); // 更新对话框的标题,将日期对象的时间设置为标题显示 } public void set24HourView(boolean is24HourView) {