diff --git a/src/net/micode/notes/ui/DateTimePicker.java b/src/net/micode/notes/ui/DateTimePicker.java index d107591..8f186d9 100644 --- a/src/net/micode/notes/ui/DateTimePicker.java +++ b/src/net/micode/notes/ui/DateTimePicker.java @@ -1,486 +1,459 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - package net.micode.notes.ui; - - import java.text.DateFormatSymbols; - import java.util.Calendar; - - import net.micode.notes.R; - - - import android.content.Context; - import android.text.format.DateFormat; - import android.view.View; - 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; - 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 String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; - - private boolean mIsAm; - - 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) { - mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); - updateDateControl(); - onDateTimeChanged(); - } - }; - - private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { - @Override - public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - 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); - isDateChanged = true; - } 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(); - } - } else { - 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) { - 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(); - if (isDateChanged) { - setCurrentYear(cal.get(Calendar.YEAR)); - setCurrentMonth(cal.get(Calendar.MONTH)); - setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); - } - } - }; - - 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; - } - - 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(); - } else { - mIsAm = true; - updateAmPmControl(); - } - } - 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); - } - updateAmPmControl(); - onDateTimeChanged(); - } - }; - - public interface OnDateTimeChangedListener { - void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute); - } - - public DateTimePicker(Context context) { - this(context, System.currentTimeMillis()); - } - - 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); - - - updateDateControl(); - updateHourControl(); - updateAmPmControl(); - - set24HourView(is24HourView); - - - setCurrentDate(date); - - setEnabled(isEnabled()); - - - mInitialising = false; - } - - @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; - } - - @Override - public boolean isEnabled() { - return mIsEnabled; - } - - /** - * Get the current date in millis - * - * @return the current date in millis - */ - public long getCurrentDateInTimeMillis() { - return mDate.getTimeInMillis(); - } - - /** - * Set the current date - * - * @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)); - } - - /** - * Set the current date - * - * @param year The current year - * @param month The current month - * @param dayOfMonth The current dayOfMonth - * @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); - } - - /** - * Get current year - * - * @return The current year - */ - public int getCurrentYear() { - return mDate.get(Calendar.YEAR); - } - - /** - * Set current year - * - * @param year The current year - */ - public void setCurrentYear(int year) { - if (!mInitialising && year == getCurrentYear()) { - return; - } - mDate.set(Calendar.YEAR, year); - updateDateControl(); - onDateTimeChanged(); - } - - /** - * Get current month in the year - * - * @return The current month in the year - */ - public int getCurrentMonth() { - return mDate.get(Calendar.MONTH); - } - - /** - * Set current month in the year - * - * @param month The month in the year - */ - public void setCurrentMonth(int month) { - if (!mInitialising && month == getCurrentMonth()) { - return; - } - mDate.set(Calendar.MONTH, month); - updateDateControl(); - onDateTimeChanged(); - } - - /** - * Get current day of the month - * - * @return The day of the month - */ - public int getCurrentDay() { - return mDate.get(Calendar.DAY_OF_MONTH); - } - - /** - * Set current day of the month - * - * @param dayOfMonth The day of the month - */ - public void setCurrentDay(int dayOfMonth) { - if (!mInitialising && dayOfMonth == getCurrentDay()) { - return; - } - 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 - */ - public int getCurrentHourOfDay() { - return mDate.get(Calendar.HOUR_OF_DAY); - } - - 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; - } - } - } - - /** - * Set current hour in 24 hour mode, in the range (0~23) - * - * @param hourOfDay - */ - 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; - if (hourOfDay > HOURS_IN_HALF_DAY) { - hourOfDay -= HOURS_IN_HALF_DAY; - } - } else { - mIsAm = true; - if (hourOfDay == 0) { - hourOfDay = HOURS_IN_HALF_DAY; - } - } - updateAmPmControl(); - } - mHourSpinner.setValue(hourOfDay); - onDateTimeChanged(); - } - - /** - * Get currentMinute - * - * @return The Current Minute - */ - public int getCurrentMinute() { - return mDate.get(Calendar.MINUTE); - } - - /** - * Set current minute - */ - public void setCurrentMinute(int minute) { - if (!mInitialising && minute == getCurrentMinute()) { - return; - } - mMinuteSpinner.setValue(minute); - mDate.set(Calendar.MINUTE, minute); - onDateTimeChanged(); - } - - /** - * @return true if this is in 24 hour view else false. - */ - public boolean is24HourView () { - return mIs24HourView; - } - - /** - * Set whether in 24 hour or AM/PM mode. - * - * @param is24HourView True for 24 hour mode. False for AM/PM mode. - */ - 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(); - } - - 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); - 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); - } - mDateSpinner.setDisplayedValues(mDateDisplayValues); - mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); - mDateSpinner.invalidate(); - } - - private void updateAmPmControl() { - if (mIs24HourView) { - mAmPmSpinner.setVisibility(View.GONE); - } else { - 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); - } 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()); - } - } - } \ No newline at end of file +package net.micode.notes.ui; + +import java.text.DateFormatSymbols; +import java.util.Calendar; + +import net.micode.notes.R; + +import android.content.Context; +import android.text.format.DateFormat; +import android.view.View; +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; + 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 String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; + + 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(); // 日期时间改变回调 + } + }; + + // 小时改变监听器 + private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + // 判断日期是否改变 + boolean isDateChanged = false; + Calendar cal = Calendar.getInstance(); + if (!mIs24HourView) { + // 非24小时制 + 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) { + 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(); // 更新上午/下午控件 + } + } else { + // 24小时制 + 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) { + 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(); // 日期时间改变回调 + if (isDateChanged) { + setCurrentYear(cal.get(Calendar.YEAR)); + setCurrentMonth(cal.get(Calendar.MONTH)); + setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); + } + } + }; + + // 分钟改变监听器 + 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; + } + 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(); + } else { + mIsAm = true; + updateAmPmControl(); + } + } + 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); + } + updateAmPmControl(); // 更新上午/下午控件 + onDateTimeChanged(); // 日期时间改变回调 + } + }; + + // 日期时间改变监听器接口 + public interface OnDateTimeChangedListener { + void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute); + } + + // 构造函数 + public DateTimePicker(Context context) { + this(context, System.currentTimeMillis()); + } + + // 带参数的构造函数 + 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); + + // 更新控件到初始状态 + updateDateControl(); + updateHourControl(); + updateAmPmControl(); + + set24HourView(is24HourView); + + // 设置为当前时间 + setCurrentDate(date); + + setEnabled(isEnabled()); + + mInitialising = false; // 初始化完成 + } + + // 设置是否启用 + @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; + } + + // 获取是否启用 + @Override + public boolean isEnabled() { + return mIsEnabled; + } + + /** + * 获取当前日期的毫秒表示 + * + * @return 当前日期的毫秒表示 + */ + public long getCurrentDateInTimeMillis() { + return mDate.getTimeInMillis(); + } + + /** + * 设置当前日期 + * + * @param date 当前日期的毫秒表示 + */ + 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)); + } + + /** + * 设置当前日期 + * + * @param year 年 + * @param month 月 + * @param dayOfMonth 日 + * @param hourOfDay 时 + * @param 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 int getCurrentYear() { + return mDate.get(Calendar.YEAR); + } + + // 设置当前年份 + public void setCurrentYear(int year) { + if (!mInitialising && year == getCurrentYear()) { + return; + } + mDate.set(Calendar.YEAR, year); + updateDateControl(); + onDateTimeChanged(); + } + + // 获取当前月份 + public int getCurrentMonth() { + return mDate.get(Calendar.MONTH); + } + + // 设置当前月份 + public void setCurrentMonth(int month) { + if (!mInitialising && month == getCurrentMonth()) { + return; + } + mDate.set(Calendar.MONTH, month); + updateDateControl(); + onDateTimeChanged(); + } + + // 获取当前日期 + public int getCurrentDay() { + return mDate.get(Calendar.DAY_OF_MONTH); + } + + // 设置当前日期 + public void setCurrentDay(int dayOfMonth) { + if (!mInitialising && dayOfMonth == getCurrentDay()) { + return; + } + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + updateDateControl(); + onDateTimeChanged(); + } + + // 获取24小时模式下的当前小时 + public int getCurrentHourOfDay() { + return mDate.get(Calendar.HOUR_OF_DAY); + } + + // 获取当前小时 + 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; + } + } + } + + // 设置当前小时 + 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; + if (hourOfDay > HOURS_IN_HALF_DAY) { + hourOfDay -= HOURS_IN_HALF_DAY; + } + } else { + mIsAm = true; + if (hourOfDay == 0) { + hourOfDay = HOURS_IN_HALF_DAY; + } + } + updateAmPmControl(); + } + mHourSpinner.setValue(hourOfDay); + onDateTimeChanged(); + } + + // 获取当前分钟 + public int getCurrentMinute() { + return mDate.get(Calendar.MINUTE); + } + + // 设置当前分钟 + public void setCurrentMinute(int minute) { + if (!mInitialising && minute == getCurrentMinute()) { + return; + } + mMinuteSpinner.setValue(minute); + mDate.set(Calendar.MINUTE, minute); + onDateTimeChanged(); + } + + /** + * 是否是24小时制 + * + * @return 如果是24小时制返回true,否则返回false + */ + public boolean is24HourView () { + return mIs24HourView; + } + + /** + * 设置是否是24小时制或上午/下午模式 + * + * @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(); + } + + // 更新日期控件 + 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); + 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); + } + mDateSpinner.setDisplayedValues(mDateDisplayValues); + mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); + mDateSpinner.invalidate(); + } + + // 更新上午/下午控件 + private void updateAmPmControl() { + if (mIs24HourView) { + mAmPmSpinner.setVisibility(View.GONE); + } else { + 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); + } else { + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); + } + } + + /** + * 设置日期时间改变监听器 + * + * @param callback 回调函数,如果为null将不进行任何操作 + */ + public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { + mOnDateTimeChangedListener = callback; + } + + // 日期时间改变回调 + private void onDateTimeChanged() { + if (mOnDateTimeChangedListener != null) { + mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(), + getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); + } + } +} \ No newline at end of file diff --git a/src/net/micode/notes/ui/DateTimePickerDialog.java b/src/net/micode/notes/ui/DateTimePickerDialog.java index dcaae5b..660a299 100644 --- a/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -1,90 +1,93 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) +/** + * DateTimePickerDialog类实现了一个日期时间选择对话框,用于在Android应用程序中选择特定的日期和时间。 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 该类继承自AlertDialog,并实现了OnClickListener接口来处理“确定”按钮的点击事件。 + * 它包含一个回调接口OnDateTimeSetListener,用于在日期时间发生更改时通知用户。 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 日期和时间的选择由内部的DateTimePicker完成,它是一个自定义的View。 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 构造函数接收一个Context和一个初始日期时间值,并进行了相应的初始化操作。 + * + * 主要方法包括set24HourView、setOnDateTimeSetListener和updateTitle。 + * + * set24HourView用于设置是否使用24小时制; + * setOnDateTimeSetListener用于设置OnDateTimeSetListener回调接口; + * updateTitle用于在日期时间更改时更新对话框的标题。 + * + * onClick方法是OnClickListener接口的回调方法,当用户点击“确定”按钮时,会触发该方法,其中会回调OnDateTimeSetListener接口的回调方法,通知用户已更改日期时间。 */ - package net.micode.notes.ui; - - import java.util.Calendar; - - import net.micode.notes.R; - import net.micode.notes.ui.DateTimePicker; - import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; - - import android.app.AlertDialog; - import android.content.Context; - import android.content.DialogInterface; - import android.content.DialogInterface.OnClickListener; - import android.text.format.DateFormat; - 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; - - public interface OnDateTimeSetListener { - void OnDateTimeSet(AlertDialog dialog, long date); - } - - public DateTimePickerDialog(Context context, long date) { - super(context); - mDateTimePicker = new DateTimePicker(context); - setView(mDateTimePicker); - 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()); - } - }); - 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()); - } - - public void set24HourView(boolean is24HourView) { - mIs24HourView = is24HourView; - } - - 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)); - } - - public void onClick(DialogInterface arg0, int arg1) { - if (mOnDateTimeSetListener != null) { - mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); - } - } - - } \ No newline at end of file +package net.micode.notes.ui; + +import java.util.Calendar; + +import net.micode.notes.R; +import net.micode.notes.ui.DateTimePicker; +import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.text.format.DateFormat; +import android.text.format.DateUtils; + +public class DateTimePickerDialog extends AlertDialog implements OnClickListener { + + 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); // 创建一个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()); // 更新对话框标题 + } + }); + mDate.setTimeInMillis(date); // 设置Calendar对象的时间值为传入的时间值 + mDate.set(Calendar.SECOND, 0); // 将秒数设为0 + mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); // 设置日期时间选择器的初始值 + setButton(context.getString(R.string.datetime_dialog_ok), this); // 设置“确定”按钮,并将当前对象作为OnClickListener + setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); // 设置“取消”按钮,点击不做任何操作 + set24HourView(DateFormat.is24HourFormat(this.getContext())); // 根据系统设置,设置是否使用24小时制 + updateTitle(mDate.getTimeInMillis()); // 更新对话框标题 + } + + public void set24HourView(boolean is24HourView) { + mIs24HourView = is24HourView; // 设置是否使用24小时制 + } + + 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; // 如果使用24小时制,则加上DateUtils.FORMAT_24HOUR,否则加上0 + setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); // 更新对话框标题 + } + + public void onClick(DialogInterface arg0, int arg1) { // OnClickListener接口的回调方法,用户点击“确定”按钮时触发 + if (mOnDateTimeSetListener != null) { + mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); // 调用回调接口的回调方法,通知用户已更改日期时间 + } + } + +} \ No newline at end of file diff --git a/src/net/micode/notes/ui/DropdownMenu.java b/src/net/micode/notes/ui/DropdownMenu.java index d037db9..9446215 100644 --- a/src/net/micode/notes/ui/DropdownMenu.java +++ b/src/net/micode/notes/ui/DropdownMenu.java @@ -1,61 +1,69 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) +/** + * DropdownMenu类实现了下拉菜单功能,用于在Android应用程序中展示一个弹出式菜单。 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 它包含一个回调接口OnMenuItemClickListener,用于在用户选择一个菜单项时通知应用程序。 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 构造函数接收一个Context、一个Button和一个菜单资源ID,并进行了相应的初始化操作。 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 主要方法包括setOnDropdownMenuItemClickListener、findItem和setTitle。 + * + * setOnDropdownMenuItemClickListener用于设置OnMenuItemClickListener回调接口; + * findItem用于查找指定ID的菜单项; + * setTitle用于设置下拉菜单按钮的文本。 + * + * 构造函数中创建了一个PopupWindow对象和一个Menu对象,它们用于显示下拉菜单和保存菜单项。 + * 在构造函数中还将菜单资源ID传递给MenuInflater,用于加载菜单项,并将下拉菜单绑定到指定的Button上。 + * + * onClick方法是OnClickListener接口的回调方法,用于在用户点击下拉菜单按钮时展示菜单。 */ - package net.micode.notes.ui; - - import android.content.Context; - import android.view.Menu; - import android.view.MenuItem; - import android.view.View; - import android.view.View.OnClickListener; - import android.widget.Button; - import android.widget.PopupMenu; - import android.widget.PopupMenu.OnMenuItemClickListener; - - import net.micode.notes.R; - - public class DropdownMenu { - private Button mButton; - private PopupMenu mPopupMenu; - private Menu mMenu; - - public DropdownMenu(Context context, Button button, int menuId) { - mButton = button; - mButton.setBackgroundResource(R.drawable.dropdown_icon); - mPopupMenu = new PopupMenu(context, mButton); - mMenu = mPopupMenu.getMenu(); - mPopupMenu.getMenuInflater().inflate(menuId, mMenu); - mButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mPopupMenu.show(); - } - }); - } - - public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { - if (mPopupMenu != null) { - mPopupMenu.setOnMenuItemClickListener(listener); - } - } - - public MenuItem findItem(int id) { - return mMenu.findItem(id); - } - - public void setTitle(CharSequence title) { - mButton.setText(title); - } - } \ No newline at end of file +package net.micode.notes.ui; + +import android.content.Context; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.PopupMenu; +import android.widget.PopupMenu.OnMenuItemClickListener; + +import net.micode.notes.R; + +public class DropdownMenu { + private Button mButton; // 下拉菜单绑定的Button + private PopupMenu mPopupMenu; // 弹出式菜单 + private Menu mMenu; // 菜单 + + public interface OnMenuItemClickListener { + boolean onMenuItemClick(MenuItem item); // 回调方法,用于在用户选择一个菜单项时通知应用程序 + } + + // 构造函数接收一个Context、一个Button和一个菜单资源ID,并进行了相应的初始化操作。 + public DropdownMenu(Context context, Button button, int menuId) { + mButton = button; + mButton.setBackgroundResource(R.drawable.dropdown_icon); + mPopupMenu = new PopupMenu(context, mButton); + mMenu = mPopupMenu.getMenu(); + mPopupMenu.getMenuInflater().inflate(menuId, mMenu); // 加载菜单项 + mButton.setOnClickListener(new OnClickListener() { // 设置Button的点击事件 + public void onClick(View v) { + mPopupMenu.show(); // 展示下拉菜单 + } + }); + } + + public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { + if (mPopupMenu != null) { + mPopupMenu.setOnMenuItemClickListener(listener); // 设置OnMenuItemClickListener回调接口 + } + } + + public MenuItem findItem(int id) { + return mMenu.findItem(id); // 查找指定ID的菜单项 + } + + public void setTitle(CharSequence title) { + mButton.setText(title); // 设置下拉菜单按钮的文本 + } +} \ No newline at end of file diff --git a/src/net/micode/notes/ui/FoldersListAdapter.java b/src/net/micode/notes/ui/FoldersListAdapter.java index b52dd41..67cc307 100644 --- a/src/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/net/micode/notes/ui/FoldersListAdapter.java @@ -1,79 +1,85 @@ /* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* FoldersListAdapter类是一个继承自CursorAdapter的适配器类,用于显示文件夹列表。 +* 它接收一个Cursor对象作为数据源,并根据数据源的内容来展示文件夹列表项。 +* +* 构造函数接收一个Context和一个Cursor对象,并进行了相应的初始化操作。 +* 主要方法包括newView和bindView。 +* +* newView方法在适配器需要创建一个新的视图时被调用,返回一个FolderListItem对象作为列表项的视图。 +* bindView方法在适配器需要绑定数据到视图时被调用,根据Cursor中的数据来更新FolderListItem的内容。 +* +* getFolderName方法用于获取指定位置的文件夹名称。 +* +* FolderListItem是一个自定义的LinearLayout子类,用于表示文件夹列表项的视图。 +* 构造函数中将folder_list_item布局文件实例化,并通过findViewById找到对应的TextView。 +* bind方法用于更新文件夹名称的显示。 +*/ +package net.micode.notes.ui; - package net.micode.notes.ui; - - import android.content.Context; - import android.database.Cursor; - import android.view.View; - import android.view.ViewGroup; - import android.widget.CursorAdapter; - import android.widget.LinearLayout; - import android.widget.TextView; - - import net.micode.notes.R; - import net.micode.notes.data.Notes; - import net.micode.notes.data.Notes.NoteColumns; - - - public class FoldersListAdapter extends CursorAdapter { - public static final String [] PROJECTION = { - NoteColumns.ID, - NoteColumns.SNIPPET - }; - - public static final int ID_COLUMN = 0; - public static final int NAME_COLUMN = 1; - - public FoldersListAdapter(Context context, Cursor c) { - super(context, c); - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return new FolderListItem(context); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - if (view instanceof 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); - } - - private class FolderListItem extends LinearLayout { - private TextView mName; - - public FolderListItem(Context context) { - super(context); - inflate(context, R.layout.folder_list_item, this); - mName = (TextView) findViewById(R.id.tv_folder_name); - } - - public void bind(String name) { - mName.setText(name); - } - } - - } \ No newline at end of file +import android.content.Context; +import android.database.Cursor; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; +import android.widget.LinearLayout; +import android.widget.TextView; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; + +public class FoldersListAdapter extends CursorAdapter { + // 声明常量数组PROJECTION,用于指定需要查询的列名 + public static final String[] PROJECTION = { + NoteColumns.ID, + NoteColumns.SNIPPET + }; + + // 声明常量ID_COLUMN和NAME_COLUMN,代表查询结果中ID和名称所在的列索引 + public static final int ID_COLUMN = 0; + public static final int NAME_COLUMN = 1; + + // 构造函数,接收Context和Cursor对象,并调用父类的构造函数进行初始化 + public FoldersListAdapter(Context context, Cursor c) { + super(context, c); + } + + // 当需要创建新的视图时被调用,返回一个FolderListItem对象作为列表项的视图 + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return new FolderListItem(context); + } + + // 当需要将数据绑定到视图时被调用,根据Cursor中的数据更新FolderListItem的内容 + @Override + public void bindView(View view, Context context, Cursor cursor) { + if (view instanceof FolderListItem) { + // 根据查询结果中的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); + } + + // FolderListItem是一个自定义的LinearLayout子类,用于表示文件夹列表项的视图 + private class FolderListItem extends LinearLayout { + private TextView mName; + + // 构造函数中将folder_list_item布局文件实例化,并通过findViewById找到对应的TextView + public FolderListItem(Context context) { + super(context); + inflate(context, R.layout.folder_list_item, this); + mName = findViewById(R.id.tv_folder_name); + } + + // 更新文件夹名称的显示 + public void bind(String name) { + mName.setText(name); + } + } +} \ No newline at end of file