diff --git a/java/net/micode/notes/ui/DateTimePicker.java b/java/net/micode/notes/ui/DateTimePicker.java index 496b0cd..60d8fbe 100644 --- a/java/net/micode/notes/ui/DateTimePicker.java +++ b/java/net/micode/notes/ui/DateTimePicker.java @@ -28,85 +28,123 @@ import android.view.View; import android.widget.FrameLayout; import android.widget.NumberPicker; +/** + * 自定义日期时间选择器控件 + * 组合使用多个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; - private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0; - private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23; - 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; - 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 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; // 日期选择器最大值 + 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; // 24小时制小时最大值 + 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; // 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; // AM/PM选择器最小值 + private static final int AMPM_SPINNER_MAX_VAL = 1; // AM/PM选择器最大值 + + // UI组件 + private final NumberPicker mDateSpinner; // 日期选择器(显示为相对日期,如今天/明天) + private final NumberPicker mHourSpinner; // 小时选择器 + private final NumberPicker mMinuteSpinner; // 分钟选择器 + private final NumberPicker mAmPmSpinner; // AM/PM选择器(12小时制时使用) + + private Calendar mDate; // 当前选择的日期时间对象 + + // 日期显示值(如"今天"、"明天"、"周日"等) private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; - private boolean mIsAm; - - private boolean mIs24HourView; - - private boolean mIsEnabled = DEFAULT_ENABLE_STATE; - - private boolean mInitialising; + // 时间状态 + private boolean mIsAm; // 是否为上午 + private boolean mIs24HourView; // 是否使用24小时制 + 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) { + // 计算日期差值并更新日历对象 mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); + // 更新日期控件显示 updateDateControl(); + // 通知日期时间变更 onDateTimeChanged(); } }; + /** + * 小时变更监听器 + * 处理12小时制和24小时制的特殊边界逻辑 + */ private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - boolean isDateChanged = false; + boolean isDateChanged = false; // 标记日期是否变更 Calendar cal = Calendar.getInstance(); + + // 12小时制特殊处理 if (!mIs24HourView) { + // 处理PM时段从11→12时(实际是23→0时,需要增加一天) if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; - } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { + } + // 处理AM时段从12→11时(实际是0→23时,需要减少一天) + else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); 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(); + + // 处理AM/PM切换点(12↔11时) + 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; // 切换AM/PM状态 + updateAmPmControl(); // 更新AM/PM控件 } - } else { + } + // 24小时制特殊处理 + else { + // 处理23→00时(增加一天) if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; - } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { + } + // 处理00→23时(减少一天) + else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } } + + // 更新实际小时值(12小时制需要转换为24小时制) 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,6 +152,7 @@ public class DateTimePicker extends FrameLayout { } } }; + private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override