|
|
|
@ -29,7 +29,7 @@ import android.widget.FrameLayout;
|
|
|
|
|
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;
|
|
|
|
@ -46,29 +46,33 @@ public class DateTimePicker extends FrameLayout {
|
|
|
|
|
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 boolean mIsAm;
|
|
|
|
|
|
|
|
|
|
private boolean mIs24HourView;
|
|
|
|
|
private boolean mIsAm;// 当前是上午还是下午
|
|
|
|
|
|
|
|
|
|
private boolean mIsEnabled = DEFAULT_ENABLE_STATE;
|
|
|
|
|
private boolean mIs24HourView;// 是否以24小时制显示时间
|
|
|
|
|
|
|
|
|
|
private boolean mInitialising;
|
|
|
|
|
private boolean mIsEnabled = DEFAULT_ENABLE_STATE;// 当前是否处于开启状态
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
@ -76,37 +80,49 @@ public class DateTimePicker extends FrameLayout {
|
|
|
|
|
private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
|
|
|
|
|
// 默认日期没有变化
|
|
|
|
|
boolean isDateChanged = false;
|
|
|
|
|
Calendar cal = Calendar.getInstance();
|
|
|
|
|
Calendar cal = Calendar.getInstance();// 新建一个Calendar对象
|
|
|
|
|
// 如果不是24小时制
|
|
|
|
|
if (!mIs24HourView) {
|
|
|
|
|
// 如果之前是PM,并且从“下午12点”切换到“上午1点”,则日期加一
|
|
|
|
|
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点”,则日期减一
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// 如果从上午和下午之间切换,则更新AM/PM控件
|
|
|
|
|
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 {
|
|
|
|
|
} else {// 如果是24小时制
|
|
|
|
|
// 如果从“23点”切换到“0点”,则日期加一
|
|
|
|
|
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) {
|
|
|
|
|
}
|
|
|
|
|
// 如果从“0点”切换到“23点”,则日期减一
|
|
|
|
|
else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) {
|
|
|
|
|
cal.setTimeInMillis(mDate.getTimeInMillis());
|
|
|
|
|
cal.add(Calendar.DAY_OF_YEAR, -1);
|
|
|
|
|
isDateChanged = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 根据新选择的时间更新日期时间对象
|
|
|
|
|
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));
|
|
|
|
@ -118,14 +134,18 @@ 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;
|
|
|
|
|
// 如果从59切换到00,则小时数加一
|
|
|
|
|
if (oldVal == maxValue && newVal == minValue) {
|
|
|
|
|
offset += 1;
|
|
|
|
|
// 如果从00切换到59,则小时数减一
|
|
|
|
|
} else if (oldVal == minValue && newVal == maxValue) {
|
|
|
|
|
offset -= 1;
|
|
|
|
|
}
|
|
|
|
|
// 如果小时数发生变化,则更新日期时间对象
|
|
|
|
|
if (offset != 0) {
|
|
|
|
|
mDate.add(Calendar.HOUR_OF_DAY, offset);
|
|
|
|
|
mHourSpinner.setValue(getCurrentHour());
|
|
|
|
@ -139,7 +159,9 @@ public class DateTimePicker extends FrameLayout {
|
|
|
|
|
updateAmPmControl();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 根据新选择的分钟数值更新日期时间对象
|
|
|
|
|
mDate.set(Calendar.MINUTE, newVal);
|
|
|
|
|
// 回调onDateTimeChanged方法,通知监听器时间发生了变化
|
|
|
|
|
onDateTimeChanged();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
@ -147,18 +169,23 @@ public class DateTimePicker extends FrameLayout {
|
|
|
|
|
private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
|
|
|
|
|
// 切换am/pm标志位
|
|
|
|
|
mIsAm = !mIsAm;
|
|
|
|
|
// 根据选择的am/pm更新日期时间对象
|
|
|
|
|
if (mIsAm) {
|
|
|
|
|
mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY);
|
|
|
|
|
} else {
|
|
|
|
|
mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY);
|
|
|
|
|
}
|
|
|
|
|
// 更新am/pm控件的状态
|
|
|
|
|
updateAmPmControl();
|
|
|
|
|
// 回调onDateTimeChanged方法,通知监听器时间发生了变化
|
|
|
|
|
onDateTimeChanged();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public interface OnDateTimeChangedListener {
|
|
|
|
|
// 定义onDateTimeChanged方法,用于监听日期和时间的变化
|
|
|
|
|
void onDateTimeChanged(DateTimePicker view, int year, int month,
|
|
|
|
|
int dayOfMonth, int hourOfDay, int minute);
|
|
|
|
|
}
|
|
|
|
|