zhangcongyu1
zhang 2 years ago
parent c1ffdc89b8
commit ad615ab7df

@ -1,486 +1,459 @@
/* package net.micode.notes.ui;
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
* import java.text.DateFormatSymbols;
* Licensed under the Apache License, Version 2.0 (the "License"); import java.util.Calendar;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at import net.micode.notes.R;
*
* http://www.apache.org/licenses/LICENSE-2.0 import android.content.Context;
* import android.text.format.DateFormat;
* Unless required by applicable law or agreed to in writing, software import android.view.View;
* distributed under the License is distributed on an "AS IS" BASIS, import android.widget.FrameLayout;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import android.widget.NumberPicker;
* See the License for the specific language governing permissions and
* limitations under the License. public class DateTimePicker extends FrameLayout {
*/
// 默认启用状态
package net.micode.notes.ui; private static final boolean DEFAULT_ENABLE_STATE = true;
import java.text.DateFormatSymbols; private static final int HOURS_IN_HALF_DAY = 12;
import java.util.Calendar; private static final int HOURS_IN_ALL_DAY = 24;
private static final int DAYS_IN_ALL_WEEK = 7;
import net.micode.notes.R; 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;
import android.content.Context; private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23;
import android.text.format.DateFormat; private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1;
import android.view.View; private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12;
import android.widget.FrameLayout; private static final int MINUT_SPINNER_MIN_VAL = 0;
import android.widget.NumberPicker; private static final int MINUT_SPINNER_MAX_VAL = 59;
private static final int AMPM_SPINNER_MIN_VAL = 0;
public class DateTimePicker extends FrameLayout { private static final int AMPM_SPINNER_MAX_VAL = 1;
private static final boolean DEFAULT_ENABLE_STATE = true;
// 日期选择器、小时选择器、分钟选择器和上午/下午选择器
private static final int HOURS_IN_HALF_DAY = 12; private final NumberPicker mDateSpinner;
private static final int HOURS_IN_ALL_DAY = 24; private final NumberPicker mHourSpinner;
private static final int DAYS_IN_ALL_WEEK = 7; private final NumberPicker mMinuteSpinner;
private static final int DATE_SPINNER_MIN_VAL = 0; private final NumberPicker mAmPmSpinner;
private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1; private Calendar mDate; // 日历对象
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 String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK];
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 boolean mIsAm; // 是否是上午
private static final int MINUT_SPINNER_MIN_VAL = 0;
private static final int MINUT_SPINNER_MAX_VAL = 59; private boolean mIs24HourView; // 是否是24小时制
private static final int AMPM_SPINNER_MIN_VAL = 0;
private static final int AMPM_SPINNER_MAX_VAL = 1; private boolean mIsEnabled = DEFAULT_ENABLE_STATE; // 是否启用标志
private final NumberPicker mDateSpinner; private boolean mInitialising; // 初始化标志
private final NumberPicker mHourSpinner;
private final NumberPicker mMinuteSpinner; private OnDateTimeChangedListener mOnDateTimeChangedListener; // 日期时间改变监听器
private final NumberPicker mAmPmSpinner;
// 日期改变监听器
private Calendar mDate; private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); // 改变日期
private boolean mIsAm; updateDateControl(); // 更新日期控件
onDateTimeChanged(); // 日期时间改变回调
private boolean mIs24HourView; }
};
private boolean mIsEnabled = DEFAULT_ENABLE_STATE;
// 小时改变监听器
private boolean mInitialising; private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
private OnDateTimeChangedListener mOnDateTimeChangedListener; public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
// 判断日期是否改变
private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { boolean isDateChanged = false;
@Override Calendar cal = Calendar.getInstance();
public void onValueChange(NumberPicker picker, int oldVal, int newVal) { if (!mIs24HourView) {
mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); // 非24小时制
updateDateControl(); if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) {
onDateTimeChanged(); 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) {
private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { cal.setTimeInMillis(mDate.getTimeInMillis());
@Override cal.add(Calendar.DAY_OF_YEAR, -1);
public void onValueChange(NumberPicker picker, int oldVal, int newVal) { isDateChanged = true;
boolean isDateChanged = false; }
Calendar cal = Calendar.getInstance(); if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY ||
if (!mIs24HourView) { oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) {
if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { mIsAm = !mIsAm; // 上午/下午切换
cal.setTimeInMillis(mDate.getTimeInMillis()); updateAmPmControl(); // 更新上午/下午控件
cal.add(Calendar.DAY_OF_YEAR, 1); }
isDateChanged = true; } else {
} else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { // 24小时制
cal.setTimeInMillis(mDate.getTimeInMillis()); if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) {
cal.add(Calendar.DAY_OF_YEAR, -1); cal.setTimeInMillis(mDate.getTimeInMillis());
isDateChanged = true; cal.add(Calendar.DAY_OF_YEAR, 1);
} isDateChanged = true;
if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) {
oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis());
mIsAm = !mIsAm; cal.add(Calendar.DAY_OF_YEAR, -1);
updateAmPmControl(); isDateChanged = true;
} }
} else { }
if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY);
cal.setTimeInMillis(mDate.getTimeInMillis()); mDate.set(Calendar.HOUR_OF_DAY, newHour);
cal.add(Calendar.DAY_OF_YEAR, 1); onDateTimeChanged(); // 日期时间改变回调
isDateChanged = true; if (isDateChanged) {
} else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { setCurrentYear(cal.get(Calendar.YEAR));
cal.setTimeInMillis(mDate.getTimeInMillis()); setCurrentMonth(cal.get(Calendar.MONTH));
cal.add(Calendar.DAY_OF_YEAR, -1); setCurrentDay(cal.get(Calendar.DAY_OF_MONTH));
isDateChanged = true; }
} }
} };
int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY);
mDate.set(Calendar.HOUR_OF_DAY, newHour); // 分钟改变监听器
onDateTimeChanged(); private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() {
if (isDateChanged) { @Override
setCurrentYear(cal.get(Calendar.YEAR)); public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
setCurrentMonth(cal.get(Calendar.MONTH)); int minValue = mMinuteSpinner.getMinValue();
setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); int maxValue = mMinuteSpinner.getMaxValue();
} int offset = 0;
} if (oldVal == maxValue && newVal == minValue) {
}; offset += 1;
} else if (oldVal == minValue && newVal == maxValue) {
private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { offset -= 1;
@Override }
public void onValueChange(NumberPicker picker, int oldVal, int newVal) { if (offset != 0) {
int minValue = mMinuteSpinner.getMinValue(); mDate.add(Calendar.HOUR_OF_DAY, offset);
int maxValue = mMinuteSpinner.getMaxValue(); mHourSpinner.setValue(getCurrentHour());
int offset = 0; updateDateControl();
int newHour = getCurrentHourOfDay();
if (oldVal == maxValue && newVal == minValue) { if (newHour >= HOURS_IN_HALF_DAY) {
offset += 1; mIsAm = false;
} else if (oldVal == minValue && newVal == maxValue) { updateAmPmControl();
offset -= 1; } else {
} mIsAm = true;
updateAmPmControl();
if (offset != 0) { }
mDate.add(Calendar.HOUR_OF_DAY, offset); }
mHourSpinner.setValue(getCurrentHour()); mDate.set(Calendar.MINUTE, newVal);
updateDateControl(); onDateTimeChanged(); // 日期时间改变回调
int newHour = getCurrentHourOfDay(); }
if (newHour >= HOURS_IN_HALF_DAY) { };
mIsAm = false;
updateAmPmControl(); // 上午/下午改变监听器
} else { private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
mIsAm = true; @Override
updateAmPmControl(); public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
} mIsAm = !mIsAm; // 切换上午/下午
} if (mIsAm) {
mDate.set(Calendar.MINUTE, newVal); mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY);
onDateTimeChanged(); } else {
} mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY);
}; }
updateAmPmControl(); // 更新上午/下午控件
private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { onDateTimeChanged(); // 日期时间改变回调
}
@Override };
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mIsAm = !mIsAm; // 日期时间改变监听器接口
if (mIsAm) { public interface OnDateTimeChangedListener {
mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); void onDateTimeChanged(DateTimePicker view, int year, int month,
} else { int dayOfMonth, int hourOfDay, int minute);
mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY); }
}
updateAmPmControl(); // 构造函数
onDateTimeChanged(); public DateTimePicker(Context context) {
} this(context, System.currentTimeMillis());
}; }
public interface OnDateTimeChangedListener { // 带参数的构造函数
void onDateTimeChanged(DateTimePicker view, int year, int month, public DateTimePicker(Context context, long date) {
int dayOfMonth, int hourOfDay, int minute); this(context, date, DateFormat.is24HourFormat(context));
} }
public DateTimePicker(Context context) { // 带参数的构造函数
this(context, System.currentTimeMillis()); public DateTimePicker(Context context, long date, boolean is24HourView) {
} super(context);
mDate = Calendar.getInstance(); // 初始化日历对象
public DateTimePicker(Context context, long date) { mInitialising = true;
this(context, date, DateFormat.is24HourFormat(context)); mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY;
} inflate(context, R.layout.datetime_picker, this); // 填充布局
public DateTimePicker(Context context, long date, boolean is24HourView) {
super(context); // 初始化日期选择器
mDate = Calendar.getInstance(); mDateSpinner = (NumberPicker) findViewById(R.id.date);
mInitialising = true; mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL);
mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL);
inflate(context, R.layout.datetime_picker, this); mDateSpinner.setOnValueChangedListener(mOnDateChangedListener);
mDateSpinner = (NumberPicker) findViewById(R.id.date);
mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); // 初始化小时选择器
mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); mHourSpinner = (NumberPicker) findViewById(R.id.hour);
mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); mHourSpinner.setOnValueChangedListener(mOnHourChangedListener);
mHourSpinner = (NumberPicker) findViewById(R.id.hour); // 初始化分钟选择器
mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL);
mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL);
mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); mMinuteSpinner.setOnLongPressUpdateInterval(100);
mMinuteSpinner.setOnLongPressUpdateInterval(100); mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);
mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);
String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();
String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();
mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); // 初始化上午/下午选择器
mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL);
mAmPmSpinner.setDisplayedValues(stringsForAmPm); mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL);
mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); mAmPmSpinner.setDisplayedValues(stringsForAmPm);
mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener);
updateDateControl(); // 更新控件到初始状态
updateHourControl(); updateDateControl();
updateAmPmControl(); updateHourControl();
updateAmPmControl();
set24HourView(is24HourView);
set24HourView(is24HourView);
setCurrentDate(date); // 设置为当前时间
setCurrentDate(date);
setEnabled(isEnabled());
setEnabled(isEnabled());
mInitialising = false; mInitialising = false; // 初始化完成
} }
@Override // 设置是否启用
public void setEnabled(boolean enabled) { @Override
if (mIsEnabled == enabled) { public void setEnabled(boolean enabled) {
return; if (mIsEnabled == enabled) {
} return;
super.setEnabled(enabled); }
mDateSpinner.setEnabled(enabled); super.setEnabled(enabled);
mMinuteSpinner.setEnabled(enabled); mDateSpinner.setEnabled(enabled);
mHourSpinner.setEnabled(enabled); mMinuteSpinner.setEnabled(enabled);
mAmPmSpinner.setEnabled(enabled); mHourSpinner.setEnabled(enabled);
mIsEnabled = enabled; mAmPmSpinner.setEnabled(enabled);
} mIsEnabled = enabled;
}
@Override
public boolean isEnabled() { // 获取是否启用
return mIsEnabled; @Override
} public boolean isEnabled() {
return mIsEnabled;
/** }
* Get the current date in millis
* /**
* @return the current date in millis *
*/ *
public long getCurrentDateInTimeMillis() { * @return
return mDate.getTimeInMillis(); */
} public long getCurrentDateInTimeMillis() {
return mDate.getTimeInMillis();
/** }
* Set the current date
* /**
* @param date The current date in millis *
*/ *
public void setCurrentDate(long date) { * @param date
Calendar cal = Calendar.getInstance(); */
cal.setTimeInMillis(date); public void setCurrentDate(long date) {
setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), Calendar cal = Calendar.getInstance();
cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); 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));
/** }
* Set the current date
* /**
* @param year The current year *
* @param month The current month *
* @param dayOfMonth The current dayOfMonth * @param year
* @param hourOfDay The current hourOfDay * @param month
* @param minute The current minute * @param dayOfMonth
*/ * @param hourOfDay
public void setCurrentDate(int year, int month, * @param minute
int dayOfMonth, int hourOfDay, int minute) { */
setCurrentYear(year); public void setCurrentDate(int year, int month,
setCurrentMonth(month); int dayOfMonth, int hourOfDay, int minute) {
setCurrentDay(dayOfMonth); setCurrentYear(year);
setCurrentHour(hourOfDay); setCurrentMonth(month);
setCurrentMinute(minute); setCurrentDay(dayOfMonth);
} setCurrentHour(hourOfDay);
setCurrentMinute(minute);
/** }
* Get current year
* // 获取当前年份
* @return The current year public int getCurrentYear() {
*/ return mDate.get(Calendar.YEAR);
public int getCurrentYear() { }
return mDate.get(Calendar.YEAR);
} // 设置当前年份
public void setCurrentYear(int year) {
/** if (!mInitialising && year == getCurrentYear()) {
* Set current year return;
* }
* @param year The current year mDate.set(Calendar.YEAR, year);
*/ updateDateControl();
public void setCurrentYear(int year) { onDateTimeChanged();
if (!mInitialising && year == getCurrentYear()) { }
return;
} // 获取当前月份
mDate.set(Calendar.YEAR, year); public int getCurrentMonth() {
updateDateControl(); return mDate.get(Calendar.MONTH);
onDateTimeChanged(); }
}
// 设置当前月份
/** public void setCurrentMonth(int month) {
* Get current month in the year if (!mInitialising && month == getCurrentMonth()) {
* return;
* @return The current month in the year }
*/ mDate.set(Calendar.MONTH, month);
public int getCurrentMonth() { updateDateControl();
return mDate.get(Calendar.MONTH); onDateTimeChanged();
} }
/** // 获取当前日期
* Set current month in the year public int getCurrentDay() {
* return mDate.get(Calendar.DAY_OF_MONTH);
* @param month The month in the year }
*/
public void setCurrentMonth(int month) { // 设置当前日期
if (!mInitialising && month == getCurrentMonth()) { public void setCurrentDay(int dayOfMonth) {
return; if (!mInitialising && dayOfMonth == getCurrentDay()) {
} return;
mDate.set(Calendar.MONTH, month); }
updateDateControl(); mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
onDateTimeChanged(); updateDateControl();
} onDateTimeChanged();
}
/**
* Get current day of the month // 获取24小时模式下的当前小时
* public int getCurrentHourOfDay() {
* @return The day of the month return mDate.get(Calendar.HOUR_OF_DAY);
*/ }
public int getCurrentDay() {
return mDate.get(Calendar.DAY_OF_MONTH); // 获取当前小时
} private int getCurrentHour() {
if (mIs24HourView){
/** return getCurrentHourOfDay();
* Set current day of the month } else {
* int hour = getCurrentHourOfDay();
* @param dayOfMonth The day of the month if (hour > HOURS_IN_HALF_DAY) {
*/ return hour - HOURS_IN_HALF_DAY;
public void setCurrentDay(int dayOfMonth) { } else {
if (!mInitialising && dayOfMonth == getCurrentDay()) { return hour == 0 ? HOURS_IN_HALF_DAY : hour;
return; }
} }
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); }
updateDateControl();
onDateTimeChanged(); // 设置当前小时
} public void setCurrentHour(int hourOfDay) {
if (!mInitialising && hourOfDay == getCurrentHourOfDay()) {
/** return;
* Get current hour in 24 hour mode, in the range (0~23) }
* @return The current hour in 24 hour mode mDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
*/ if (!mIs24HourView) {
public int getCurrentHourOfDay() { if (hourOfDay >= HOURS_IN_HALF_DAY) {
return mDate.get(Calendar.HOUR_OF_DAY); mIsAm = false;
} if (hourOfDay > HOURS_IN_HALF_DAY) {
hourOfDay -= HOURS_IN_HALF_DAY;
private int getCurrentHour() { }
if (mIs24HourView){ } else {
return getCurrentHourOfDay(); mIsAm = true;
} else { if (hourOfDay == 0) {
int hour = getCurrentHourOfDay(); hourOfDay = HOURS_IN_HALF_DAY;
if (hour > HOURS_IN_HALF_DAY) { }
return hour - HOURS_IN_HALF_DAY; }
} else { updateAmPmControl();
return hour == 0 ? HOURS_IN_HALF_DAY : hour; }
} mHourSpinner.setValue(hourOfDay);
} onDateTimeChanged();
} }
/** // 获取当前分钟
* Set current hour in 24 hour mode, in the range (0~23) public int getCurrentMinute() {
* return mDate.get(Calendar.MINUTE);
* @param hourOfDay }
*/
public void setCurrentHour(int hourOfDay) { // 设置当前分钟
if (!mInitialising && hourOfDay == getCurrentHourOfDay()) { public void setCurrentMinute(int minute) {
return; if (!mInitialising && minute == getCurrentMinute()) {
} return;
mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); }
if (!mIs24HourView) { mMinuteSpinner.setValue(minute);
if (hourOfDay >= HOURS_IN_HALF_DAY) { mDate.set(Calendar.MINUTE, minute);
mIsAm = false; onDateTimeChanged();
if (hourOfDay > HOURS_IN_HALF_DAY) { }
hourOfDay -= HOURS_IN_HALF_DAY;
} /**
} else { * 24
mIsAm = true; *
if (hourOfDay == 0) { * @return 24truefalse
hourOfDay = HOURS_IN_HALF_DAY; */
} public boolean is24HourView () {
} return mIs24HourView;
updateAmPmControl(); }
}
mHourSpinner.setValue(hourOfDay); /**
onDateTimeChanged(); * 24/
} *
* @param is24HourView true 24false /
/** */
* Get currentMinute public void set24HourView(boolean is24HourView) {
* if (mIs24HourView == is24HourView) {
* @return The Current Minute return;
*/ }
public int getCurrentMinute() { mIs24HourView = is24HourView;
return mDate.get(Calendar.MINUTE); mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE);
} int hour = getCurrentHourOfDay();
updateHourControl();
/** setCurrentHour(hour);
* Set current minute updateAmPmControl();
*/ }
public void setCurrentMinute(int minute) {
if (!mInitialising && minute == getCurrentMinute()) { // 更新日期控件
return; private void updateDateControl() {
} Calendar cal = Calendar.getInstance();
mMinuteSpinner.setValue(minute); cal.setTimeInMillis(mDate.getTimeInMillis());
mDate.set(Calendar.MINUTE, minute); cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1);
onDateTimeChanged(); 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);
* @return true if this is in 24 hour view else false. }
*/ mDateSpinner.setDisplayedValues(mDateDisplayValues);
public boolean is24HourView () { mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2);
return mIs24HourView; mDateSpinner.invalidate();
} }
/** // 更新上午/下午控件
* Set whether in 24 hour or AM/PM mode. private void updateAmPmControl() {
* if (mIs24HourView) {
* @param is24HourView True for 24 hour mode. False for AM/PM mode. mAmPmSpinner.setVisibility(View.GONE);
*/ } else {
public void set24HourView(boolean is24HourView) { int index = mIsAm ? Calendar.AM : Calendar.PM;
if (mIs24HourView == is24HourView) { mAmPmSpinner.setValue(index);
return; mAmPmSpinner.setVisibility(View.VISIBLE);
} }
mIs24HourView = is24HourView; }
mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE);
int hour = getCurrentHourOfDay(); // 更新小时控件
updateHourControl(); private void updateHourControl() {
setCurrentHour(hour); if (mIs24HourView) {
updateAmPmControl(); mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW);
} mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW);
} else {
private void updateDateControl() { mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW);
Calendar cal = Calendar.getInstance(); mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW);
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); *
mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); *
} * @param callback null
mDateSpinner.setDisplayedValues(mDateDisplayValues); */
mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) {
mDateSpinner.invalidate(); mOnDateTimeChangedListener = callback;
} }
private void updateAmPmControl() { // 日期时间改变回调
if (mIs24HourView) { private void onDateTimeChanged() {
mAmPmSpinner.setVisibility(View.GONE); if (mOnDateTimeChangedListener != null) {
} else { mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(),
int index = mIsAm ? Calendar.AM : Calendar.PM; getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute());
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);
} else {
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW);
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW);
}
}
/**
* 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;
}
private void onDateTimeChanged() {
if (mOnDateTimeChangedListener != null) {
mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(),
getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute());
}
}
}

@ -1,90 +1,93 @@
/* /**
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * DateTimePickerDialogAndroid
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * AlertDialogOnClickListener
* you may not use this file except in compliance with the License. * OnDateTimeSetListener
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * DateTimePickerView
* *
* Unless required by applicable law or agreed to in writing, software * Context
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * set24HourViewsetOnDateTimeSetListenerupdateTitle
* See the License for the specific language governing permissions and *
* limitations under the License. * set24HourView使24
* setOnDateTimeSetListenerOnDateTimeSetListener
* updateTitle
*
* onClickOnClickListenerOnDateTimeSetListener
*/ */
package net.micode.notes.ui; package net.micode.notes.ui;
import java.util.Calendar; import java.util.Calendar;
import net.micode.notes.R; import net.micode.notes.R;
import net.micode.notes.ui.DateTimePicker; import net.micode.notes.ui.DateTimePicker;
import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.text.format.DateUtils; import android.text.format.DateUtils;
public class DateTimePickerDialog extends AlertDialog implements OnClickListener { public class DateTimePickerDialog extends AlertDialog implements OnClickListener {
private Calendar mDate = Calendar.getInstance(); private Calendar mDate = Calendar.getInstance(); // 创建一个表示日期时间的Calendar对象初始化为当前时间
private boolean mIs24HourView; private boolean mIs24HourView; // 是否使用24小时制
private OnDateTimeSetListener mOnDateTimeSetListener; private OnDateTimeSetListener mOnDateTimeSetListener; // 回调接口,用于在日期时间发生更改时通知用户
private DateTimePicker mDateTimePicker; private DateTimePicker mDateTimePicker; // 日期时间选择器
public interface OnDateTimeSetListener { public interface OnDateTimeSetListener {
void OnDateTimeSet(AlertDialog dialog, long date); void OnDateTimeSet(AlertDialog dialog, long date); // 回调方法,用于通知用户已更改日期时间
} }
public DateTimePickerDialog(Context context, long date) { public DateTimePickerDialog(Context context, long date) {
super(context); super(context); // 调用父类的构造方法
mDateTimePicker = new DateTimePicker(context); mDateTimePicker = new DateTimePicker(context); // 创建一个DateTimePicker对象
setView(mDateTimePicker); setView(mDateTimePicker); // 将DateTimePicker设置为对话框的视图
mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { // 设置日期时间选择器的回调接口
public void onDateTimeChanged(DateTimePicker view, int year, int month, public void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute) { int dayOfMonth, int hourOfDay, int minute) {
mDate.set(Calendar.YEAR, year); mDate.set(Calendar.YEAR, year); // 设置年份
mDate.set(Calendar.MONTH, month); mDate.set(Calendar.MONTH, month); // 设置月份
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); // 设置日
mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); // 设置小时
mDate.set(Calendar.MINUTE, minute); mDate.set(Calendar.MINUTE, minute); // 设置分钟
updateTitle(mDate.getTimeInMillis()); updateTitle(mDate.getTimeInMillis()); // 更新对话框标题
} }
}); });
mDate.setTimeInMillis(date); mDate.setTimeInMillis(date); // 设置Calendar对象的时间值为传入的时间值
mDate.set(Calendar.SECOND, 0); mDate.set(Calendar.SECOND, 0); // 将秒数设为0
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); // 设置日期时间选择器的初始值
setButton(context.getString(R.string.datetime_dialog_ok), this); setButton(context.getString(R.string.datetime_dialog_ok), this); // 设置“确定”按钮并将当前对象作为OnClickListener
setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); // 设置“取消”按钮,点击不做任何操作
set24HourView(DateFormat.is24HourFormat(this.getContext())); set24HourView(DateFormat.is24HourFormat(this.getContext())); // 根据系统设置设置是否使用24小时制
updateTitle(mDate.getTimeInMillis()); updateTitle(mDate.getTimeInMillis()); // 更新对话框标题
} }
public void set24HourView(boolean is24HourView) { public void set24HourView(boolean is24HourView) {
mIs24HourView = is24HourView; mIs24HourView = is24HourView; // 设置是否使用24小时制
} }
public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
mOnDateTimeSetListener = callBack; mOnDateTimeSetListener = callBack; // 设置回调接口,用于在日期时间发生更改时通知用户
} }
private void updateTitle(long date) { private void updateTitle(long date) {
int flag = int flag =
DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_YEAR |
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_SHOW_TIME; DateUtils.FORMAT_SHOW_TIME;
flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; // 如果使用24小时制则加上DateUtils.FORMAT_24HOUR否则加上0
setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); // 更新对话框标题
} }
public void onClick(DialogInterface arg0, int arg1) { public void onClick(DialogInterface arg0, int arg1) { // OnClickListener接口的回调方法用户点击“确定”按钮时触发
if (mOnDateTimeSetListener != null) { if (mOnDateTimeSetListener != null) {
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); // 调用回调接口的回调方法,通知用户已更改日期时间
} }
} }
} }

@ -1,61 +1,69 @@
/* /**
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * DropdownMenuAndroid
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * OnMenuItemClickListener
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * ContextButtonID
* *
* Unless required by applicable law or agreed to in writing, software * setOnDropdownMenuItemClickListenerfindItemsetTitle
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * setOnDropdownMenuItemClickListenerOnMenuItemClickListener
* See the License for the specific language governing permissions and * findItemID
* limitations under the License. * setTitle
*
* PopupWindowMenu
* IDMenuInflaterButton
*
* onClickOnClickListener
*/ */
package net.micode.notes.ui; package net.micode.notes.ui;
import android.content.Context; import android.content.Context;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.PopupMenu.OnMenuItemClickListener;
import net.micode.notes.R; import net.micode.notes.R;
public class DropdownMenu { public class DropdownMenu {
private Button mButton; private Button mButton; // 下拉菜单绑定的Button
private PopupMenu mPopupMenu; private PopupMenu mPopupMenu; // 弹出式菜单
private Menu mMenu; private Menu mMenu; // 菜单
public DropdownMenu(Context context, Button button, int menuId) { public interface OnMenuItemClickListener {
mButton = button; boolean onMenuItemClick(MenuItem item); // 回调方法,用于在用户选择一个菜单项时通知应用程序
mButton.setBackgroundResource(R.drawable.dropdown_icon); }
mPopupMenu = new PopupMenu(context, mButton);
mMenu = mPopupMenu.getMenu(); // 构造函数接收一个Context、一个Button和一个菜单资源ID并进行了相应的初始化操作。
mPopupMenu.getMenuInflater().inflate(menuId, mMenu); public DropdownMenu(Context context, Button button, int menuId) {
mButton.setOnClickListener(new OnClickListener() { mButton = button;
public void onClick(View v) { mButton.setBackgroundResource(R.drawable.dropdown_icon);
mPopupMenu.show(); mPopupMenu = new PopupMenu(context, mButton);
} mMenu = mPopupMenu.getMenu();
}); mPopupMenu.getMenuInflater().inflate(menuId, mMenu); // 加载菜单项
} mButton.setOnClickListener(new OnClickListener() { // 设置Button的点击事件
public void onClick(View v) {
public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { mPopupMenu.show(); // 展示下拉菜单
if (mPopupMenu != null) { }
mPopupMenu.setOnMenuItemClickListener(listener); });
} }
}
public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) {
public MenuItem findItem(int id) { if (mPopupMenu != null) {
return mMenu.findItem(id); mPopupMenu.setOnMenuItemClickListener(listener); // 设置OnMenuItemClickListener回调接口
} }
}
public void setTitle(CharSequence title) {
mButton.setText(title); public MenuItem findItem(int id) {
} return mMenu.findItem(id); // 查找指定ID的菜单项
} }
public void setTitle(CharSequence title) {
mButton.setText(title); // 设置下拉菜单按钮的文本
}
}

@ -1,79 +1,85 @@
/* /*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * FoldersListAdapterCursorAdapter
* * Cursor
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. * ContextCursor
* You may obtain a copy of the License at * newViewbindView
* *
* http://www.apache.org/licenses/LICENSE-2.0 * newViewFolderListItem
* * bindViewCursorFolderListItem
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, * getFolderName
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * FolderListItemLinearLayout
* limitations under the License. * folder_list_itemfindViewByIdTextView
*/ * bind
*/
package net.micode.notes.ui;
package net.micode.notes.ui; import android.content.Context;
import android.database.Cursor;
import android.content.Context; import android.view.View;
import android.database.Cursor; import android.view.ViewGroup;
import android.view.View; import android.widget.CursorAdapter;
import android.view.ViewGroup; import android.widget.LinearLayout;
import android.widget.CursorAdapter; import android.widget.TextView;
import android.widget.LinearLayout;
import android.widget.TextView; import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.R; import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns; public class FoldersListAdapter extends CursorAdapter {
// 声明常量数组PROJECTION用于指定需要查询的列名
public static final String[] PROJECTION = {
public class FoldersListAdapter extends CursorAdapter { NoteColumns.ID,
public static final String [] PROJECTION = { NoteColumns.SNIPPET
NoteColumns.ID, };
NoteColumns.SNIPPET
}; // 声明常量ID_COLUMN和NAME_COLUMN代表查询结果中ID和名称所在的列索引
public static final int ID_COLUMN = 0;
public static final int ID_COLUMN = 0; public static final int NAME_COLUMN = 1;
public static final int NAME_COLUMN = 1;
// 构造函数接收Context和Cursor对象并调用父类的构造函数进行初始化
public FoldersListAdapter(Context context, Cursor c) { public FoldersListAdapter(Context context, Cursor c) {
super(context, c); super(context, c);
} }
@Override // 当需要创建新的视图时被调用返回一个FolderListItem对象作为列表项的视图
public View newView(Context context, Cursor cursor, ViewGroup parent) { @Override
return new FolderListItem(context); public View newView(Context context, Cursor cursor, ViewGroup parent) {
} return new FolderListItem(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) { // 当需要将数据绑定到视图时被调用根据Cursor中的数据更新FolderListItem的内容
if (view instanceof FolderListItem) { @Override
String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context public void bindView(View view, Context context, Cursor cursor) {
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); if (view instanceof FolderListItem) {
((FolderListItem) view).bind(folderName); // 根据查询结果中的ID和名称更新FolderListItem的内容
} String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
} ((FolderListItem) view).bind(folderName);
}
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); 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;
// FolderListItem是一个自定义的LinearLayout子类用于表示文件夹列表项的视图
public FolderListItem(Context context) { private class FolderListItem extends LinearLayout {
super(context); private TextView mName;
inflate(context, R.layout.folder_list_item, this);
mName = (TextView) findViewById(R.id.tv_folder_name); // 构造函数中将folder_list_item布局文件实例化并通过findViewById找到对应的TextView
} public FolderListItem(Context context) {
super(context);
public void bind(String name) { inflate(context, R.layout.folder_list_item, this);
mName.setText(name); mName = findViewById(R.id.tv_folder_name);
} }
}
// 更新文件夹名称的显示
} public void bind(String name) {
mName.setText(name);
}
}
}
Loading…
Cancel
Save