From 2ae54b9a3c9b6b511228418751136ca399fc16a9 Mon Sep 17 00:00:00 2001 From: Ryuki <2124555323@qq.com> Date: Thu, 28 Dec 2023 20:40:59 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/net/micode/notes/ui/DateTimePicker.java | 112 ++++++++++++++---- .../micode/notes/ui/DateTimePickerDialog.java | 36 ++++-- 2 files changed, 113 insertions(+), 35 deletions(-) diff --git a/src/net/micode/notes/ui/DateTimePicker.java b/src/net/micode/notes/ui/DateTimePicker.java index 496b0cd..f85e31c 100644 --- a/src/net/micode/notes/ui/DateTimePicker.java +++ b/src/net/micode/notes/ui/DateTimePicker.java @@ -28,42 +28,67 @@ import android.view.View; import android.widget.FrameLayout; import android.widget.NumberPicker; +//自定义的日期时间选择器控件,继承自FrameLayout。 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; + + //根据一周的天数设置日期选择器(NumberPicker)的最大和最小值 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; 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; 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; + + //AM/PM 选择器的最大和最小值 private static final int AMPM_SPINNER_MIN_VAL = 0; private static final int AMPM_SPINNER_MAX_VAL = 1; + //NumberPicker 控件的实例引用 private final NumberPicker mDateSpinner; private final NumberPicker mHourSpinner; private final NumberPicker mMinuteSpinner; private final NumberPicker mAmPmSpinner; + + //用于存储和处理日期的Calendar实例 private Calendar mDate; + //日期显示的数据,用于存储一周内每一天的描述 private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; + //是否为上午的变量 private boolean mIsAm; + //是否为24小时视图的标志变量 private boolean mIs24HourView; + //控件的启用状态 private boolean mIsEnabled = DEFAULT_ENABLE_STATE; + //是否正在初始化的标志变量,避免在初始化过程中触发事件 private boolean mInitialising; + //日期变化监听器接口,用于在日期时间改变时通知用户 private OnDateTimeChangedListener mOnDateTimeChangedListener; + //日期改变监听器 private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { @@ -73,6 +98,7 @@ public class DateTimePicker extends FrameLayout { } }; + //小时改变监听器 private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { @@ -115,6 +141,7 @@ public class DateTimePicker extends FrameLayout { } }; + //分钟改变监听器 private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { @@ -144,6 +171,7 @@ public class DateTimePicker extends FrameLayout { } }; + //AM/PM 改变监听器 private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { @@ -158,24 +186,30 @@ public class DateTimePicker extends FrameLayout { } }; + //日期时间变化的监听器接口,需要被实现来响应日期时间的任何变化 public interface OnDateTimeChangedListener { void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute); } + //构造器1:当没有指定日期时,默认使用当前的系统时间 public DateTimePicker(Context context) { this(context, System.currentTimeMillis()); } + //构造器2:允许在创建控件时指定一个日期 public DateTimePicker(Context context, long date) { this(context, date, DateFormat.is24HourFormat(context)); } + //构造器3:最完整的构造器,允许指定日期和是否以24小时格式显示时间 public DateTimePicker(Context context, long date, boolean is24HourView) { - super(context); - mDate = Calendar.getInstance(); - mInitialising = true; + super(context); //调用父类构造器 + mDate = Calendar.getInstance(); //初始化当前日期和时间的日历实例 + mInitialising = true; //开始初始化流程的标志 + //设置是否用上午/下午模式还是24小时制 mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; + //通过XML布局文件创建视图 inflate(context, R.layout.datetime_picker, this); mDateSpinner = (NumberPicker) findViewById(R.id.date); @@ -203,17 +237,20 @@ public class DateTimePicker extends FrameLayout { updateHourControl(); updateAmPmControl(); + //更新24小时播放视图 set24HourView(is24HourView); - // set to current time + // set to current time设置当前日期到指定的时间 setCurrentDate(date); + //更新控件的启用状态 setEnabled(isEnabled()); - // set the content descriptions - mInitialising = false; + // set the content descriptions 设置内容描述 + mInitialising = false; //初始化完成 } + //设置控件是否可用,并且使内部的NumberPicker控件与之匹配 @Override public void setEnabled(boolean enabled) { if (mIsEnabled == enabled) { @@ -227,6 +264,7 @@ public class DateTimePicker extends FrameLayout { mIsEnabled = enabled; } + //检查控件是否可以与用户交互 @Override public boolean isEnabled() { return mIsEnabled; @@ -237,6 +275,8 @@ public class DateTimePicker extends FrameLayout { * * @return the current date in millis */ + + //获取当前的日期及时间 public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); } @@ -246,6 +286,8 @@ public class DateTimePicker extends FrameLayout { * * @param date The current date in millis */ + + //设置当前日期和时间 public void setCurrentDate(long date) { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(date); @@ -262,6 +304,8 @@ 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); @@ -276,6 +320,8 @@ public class DateTimePicker extends FrameLayout { * * @return The current year */ + + //获取和设置当前的年份 public int getCurrentYear() { return mDate.get(Calendar.YEAR); } @@ -299,6 +345,8 @@ public class DateTimePicker extends FrameLayout { * * @return The current month in the year */ + + //获取和设置当前的月份 public int getCurrentMonth() { return mDate.get(Calendar.MONTH); } @@ -322,6 +370,8 @@ public class DateTimePicker extends FrameLayout { * * @return The day of the month */ + + //获取和设置当前的日期(天) public int getCurrentDay() { return mDate.get(Calendar.DAY_OF_MONTH); } @@ -344,6 +394,8 @@ public class DateTimePicker extends FrameLayout { * Get current hour in 24 hour mode, in the range (0~23) * @return The current hour in 24 hour mode */ + + //获取和设置当前的小时(24时制) public int getCurrentHourOfDay() { return mDate.get(Calendar.HOUR_OF_DAY); } @@ -394,6 +446,8 @@ public class DateTimePicker extends FrameLayout { * * @return The Current Minute */ + + //获取和设置当前的分钟数 public int getCurrentMinute() { return mDate.get(Calendar.MINUTE); } @@ -413,6 +467,8 @@ public class DateTimePicker extends FrameLayout { /** * @return true if this is in 24 hour view else false. */ + + //判断是否为24小时格式 public boolean is24HourView () { return mIs24HourView; } @@ -422,6 +478,8 @@ public class DateTimePicker extends FrameLayout { * * @param is24HourView True for 24 hour mode. False for AM/PM mode. */ + + //设置为24小时格式或者 AM/PM格式 public void set24HourView(boolean is24HourView) { if (mIs24HourView == is24HourView) { return; @@ -434,37 +492,40 @@ public class DateTimePicker extends FrameLayout { 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(); //获取当前日期的日历实例 + cal.setTimeInMillis(mDate.getTimeInMillis()); //设置日历时间为当前控件已选择的时间 + cal.add(Calendar.DAY_OF_YEAR, -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); + cal.add(Calendar.DAY_OF_YEAR, 1); //为日期数组的每一天累加一天 mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); } - mDateSpinner.setDisplayedValues(mDateDisplayValues); - mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); - mDateSpinner.invalidate(); + mDateSpinner.setDisplayedValues(mDateDisplayValues); //设置日期选择器显示值为新的日期列表 + mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); //设置选择器的当前值为中间的日期 + mDateSpinner.invalidate(); //刷新视图状态 } + //更新AM/PM显示控制,以显示或隐藏AM/PM选择器,具体取决于是否采用24小时视图 private void updateAmPmControl() { if (mIs24HourView) { - mAmPmSpinner.setVisibility(View.GONE); + mAmPmSpinner.setVisibility(View.GONE); //如果是24小时制,则隐藏AM/PM选择器 } 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); //设置AM/PM选择器值为当前AM或者PM + mAmPmSpinner.setVisibility(View.VISIBLE); //显示AM/PM选择器 } } + //更新小时显示控制,调整小时选择器的最小和最大值,以匹配所选择的24小时制或12小时制 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,则小时选择器最小值设置为0/1 + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); //小时选择器的最大值设置为23/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,小时选择器的最小值 1 + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); // 小时选择器的最大值 12 } } @@ -472,14 +533,17 @@ public class DateTimePicker extends FrameLayout { * Set the callback that indicates the 'Set' button has been pressed. * @param callback the callback, if null will do nothing */ + + //设置一个回调函数,当用户点击"设置"时出发 public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { - mOnDateTimeChangedListener = callback; + mOnDateTimeChangedListener = callback; //赋值回调接口 } + //调用回调函数,当日期或者时间发生改变时,这个方法通知订阅了监听器的客户端 private void onDateTimeChanged() { if (mOnDateTimeChangedListener != null) { mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(), - getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); + getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); //传递更新后的值给监听器 } } } diff --git a/src/net/micode/notes/ui/DateTimePickerDialog.java b/src/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..d7ef4fc 100644 --- a/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -29,61 +29,75 @@ import android.content.DialogInterface.OnClickListener; import android.text.format.DateFormat; import android.text.format.DateUtils; +//继承自 AlertDialog,包含日期和时间选择的功能 public class DateTimePickerDialog extends AlertDialog implements OnClickListener { + //用于存储当前选择日期和时间 private Calendar mDate = Calendar.getInstance(); + //标记是否使用24小时视图展示时间 private boolean mIs24HourView; + //回调接口定义,当日期和时间设定后激活 private OnDateTimeSetListener mOnDateTimeSetListener; + //本对话框包含的日期和时间选择器视图 private DateTimePicker mDateTimePicker; - + //定义回调接口,用于通知调用者日期和时间已经设定 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } + //DateTimePickerDialog构造函数 public DateTimePickerDialog(Context context, long date) { - super(context); - mDateTimePicker = new DateTimePicker(context); - setView(mDateTimePicker); + super(context); //调用AlertDiaglog构造函数 + mDateTimePicker = new DateTimePicker(context);//创建一个新的DateTimePicker实例 + setView(mDateTimePicker);//将DateTimePicker视图添加到对话框中 + //注册一个回调,以在日期和时间改变时更新内部的Calendar实例 mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { public void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute) { + //更新Calendar实例的年、月、日、时、分 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()); + updateTitle(mDate.getTimeInMillis()); //更新对话框标题显示的日期 } }); - mDate.setTimeInMillis(date); - mDate.set(Calendar.SECOND, 0); - mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); + mDate.setTimeInMillis(date); // 将对话框初始化为传入的日期和时间值 + 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); + //设置是否使用24小时视图 set24HourView(DateFormat.is24HourFormat(this.getContext())); - updateTitle(mDate.getTimeInMillis()); + updateTitle(mDate.getTimeInMillis()); // 初始对话框标题显示的日期和时间 } + //设置时间是否显示为24小时视图 public void set24HourView(boolean is24HourView) { mIs24HourView = is24HourView; } + //设置DateTimeSet监听回调 public void setOnDateTimeSetListener(OnDateTimeSetListener 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_24HOUR; - setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); + setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); // 格式化时间并设置标题 } + //点击对话框按钮调用,通知监听者时间已设置 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { - mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); + mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); // 激活回调传递当前设置的日期和时间 } }