diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2010-12-19 16:03:07 -0800 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2010-12-22 03:29:29 -0800 |
commit | 28104e1de5595a22a6987181b13ddeb192739afd (patch) | |
tree | 8cbe0cad69177bc7bd85a51eb054160c7648712c /core/java | |
parent | 8177ebe403feb413f640a645eb23ff9a254f73c4 (diff) | |
download | frameworks_base-28104e1de5595a22a6987181b13ddeb192739afd.zip frameworks_base-28104e1de5595a22a6987181b13ddeb192739afd.tar.gz frameworks_base-28104e1de5595a22a6987181b13ddeb192739afd.tar.bz2 |
3298147 DatePicker dialog does not provide mechanism for specifying range from which to select
Change-Id: Ib5dd7db90ccc5b4d984914c481118049ac3648fe
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/DatePickerDialog.java | 23 | ||||
-rw-r--r-- | core/java/android/widget/DatePicker.java | 61 | ||||
-rw-r--r-- | core/java/android/widget/DayPicker.java | 64 | ||||
-rw-r--r-- | core/java/android/widget/NumberPicker.java | 4 |
4 files changed, 118 insertions, 34 deletions
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index 448b3ef..e6e55ee 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -21,7 +21,6 @@ import com.android.internal.R; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; -import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -118,6 +117,28 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, mDatePicker.init(year, month, day, null); } + /** + * Sets the range of years in which dates can be selected. + * <p> + * Note: If the range is set to a value that does not include the currently + * selected date the value of the picker shown by this dialog will be + * updated to the closest date in the range. + * </p> + * + * @param startYear The start year of the range. + * @param endYear The end year of the range. + */ + public void setRange(int startYear, int endYear) { + mDatePicker.setRange(startYear, endYear); + } + + /** + * Sets the current date. + * + * @param year The date year. + * @param monthOfYear The date month. + * @param dayOfMonth The date day of month. + */ public void updateDate(int year, int monthOfYear, int dayOfMonth) { mDatePicker.updateDate(year, monthOfYear, dayOfMonth); } diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index e98c0bd..668490d 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -104,6 +104,14 @@ public class DatePicker extends FrameLayout { } }; + // mini-month day-picker + mMiniMonthDayPicker = (DayPicker) findViewById(R.id.mini_month_day_picker); + mMiniMonthDayPicker.setOnDateChangeListener(new DayPicker.OnSelectedDayChangeListener() { + public void onSelectedDayChange(DayPicker view, int year, int month, int monthDay) { + updateDateUnchecked(year, month, monthDay); + } + }); + // day mDayPicker = (NumberPicker) findViewById(R.id.day); mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); @@ -121,24 +129,11 @@ public class DatePicker extends FrameLayout { mYearPicker.setOnLongPressUpdateInterval(100); mYearPicker.setOnChangeListener(onChangeListener); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker); - int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR); - int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR); - mYearPicker.setRange(mStartYear, mEndYear); + int startYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR); + int endYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR); + setRange(startYear, endYear); a.recycle(); - // mini-month day-picker - mMiniMonthDayPicker = (DayPicker) findViewById(R.id.mini_month_day_picker); - mTempCalendar.clear(); - mTempCalendar.set(mStartYear, 0, 1); - Calendar endRangeDate = (Calendar) mTempCalendar.clone(); - endRangeDate.set(mEndYear, 11, 31); - mMiniMonthDayPicker.setRange(mTempCalendar, endRangeDate); - mMiniMonthDayPicker.setOnDateChangeListener(new DayPicker.OnSelectedDayChangeListener() { - public void onSelectedDayChange(DayPicker view, int year, int month, int monthDay) { - updateDateUnchecked(year, month, monthDay); - } - }); - // initialize to current date mTempCalendar.setTimeInMillis(System.currentTimeMillis()); init(mTempCalendar.get(Calendar.YEAR), mTempCalendar.get(Calendar.MONTH), @@ -148,6 +143,40 @@ public class DatePicker extends FrameLayout { reorderPickers(); } + /** + * Sets the range of years in which dates can be selected. + * <p> + * Note: If the range is set to a value that does not include the currently + * selected date the value of this picker will be updated to the closest + * date in the range. + * </p> + * + * @param startYear The start year of the range. + * @param endYear The end year of the range. + */ + public void setRange(int startYear, int endYear) { + // set ranges of the widgets + mYearPicker.setRange(startYear, endYear); + mTempCalendar.clear(); + Calendar startRangeDate = (Calendar) mTempCalendar.clone(); + startRangeDate.set(startYear, 0, 1); + Calendar endRangeDate = (Calendar) mTempCalendar.clone(); + endRangeDate.set(endYear, 11, 31); + mMiniMonthDayPicker.setRange(startRangeDate, endRangeDate); + + // update state if current date is outside of the range + mTempCalendar.set(Calendar.YEAR, getYear()); + mTempCalendar.set(Calendar.MONTH, getMonth()); + mTempCalendar.set(Calendar.DAY_OF_MONTH, getDayOfMonth()); + if (mTempCalendar.before(startRangeDate)) { + updateDate(startRangeDate.get(Calendar.YEAR), startRangeDate.get(Calendar.MONTH), + startRangeDate.get(Calendar.DAY_OF_MONTH)); + } else if (mTempCalendar.after(endRangeDate)) { + updateDate(endRangeDate.get(Calendar.YEAR), endRangeDate.get(Calendar.MONTH), + endRangeDate.get(Calendar.DAY_OF_MONTH)); + } + } + @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); diff --git a/core/java/android/widget/DayPicker.java b/core/java/android/widget/DayPicker.java index cdf51f7..02805be 100644 --- a/core/java/android/widget/DayPicker.java +++ b/core/java/android/widget/DayPicker.java @@ -366,22 +366,38 @@ public class DayPicker extends FrameLayout { * @param endRangeDate The end date. */ public void setRange(Calendar startRangeDate, Calendar endRangeDate) { - boolean doSetupAdapter = false; + boolean rangeChanged = false; if (mRangeStartDate.get(Calendar.DAY_OF_YEAR) != startRangeDate.get(Calendar.DAY_OF_YEAR) || mRangeStartDate.get(Calendar.YEAR) != startRangeDate.get(Calendar.YEAR)) { mRangeStartDate.setTimeInMillis(startRangeDate.getTimeInMillis()); mRangeStartDate.setTimeZone(startRangeDate.getTimeZone()); - doSetupAdapter = true; + rangeChanged = true; } if (mRangeEndDate.get(Calendar.DAY_OF_YEAR) != endRangeDate.get(Calendar.DAY_OF_YEAR) || mRangeEndDate.get(Calendar.YEAR) != endRangeDate.get(Calendar.YEAR)) { mRangeEndDate.setTimeInMillis(endRangeDate.getTimeInMillis()); mRangeEndDate.setTimeZone(endRangeDate.getTimeZone()); - doSetupAdapter = true; - + rangeChanged = true; } - if (doSetupAdapter) { - setUpAdapter(); + + if (!rangeChanged) { + return; + } + + // now recreate the adapter since we have a new range to handle + mAdapter = null; + setUpAdapter(); + + // set the current date to today if in the range + // otherwise to the closest end of the range + mTempCalendar.clear(); + mTempCalendar.setTimeInMillis(System.currentTimeMillis()); + if (mTempCalendar.before(mRangeStartDate)) { + goTo(mRangeStartDate, false, true, true); + } else if (mTempCalendar.after(mRangeEndDate)) { + goTo(mRangeEndDate, false, true, true); + } else { + goTo(mTempCalendar, false, true, true); } } @@ -629,7 +645,6 @@ public class DayPicker extends FrameLayout { } // Figure out where we are - int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0; long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom(); // If we have moved since our last call update the direction @@ -645,6 +660,7 @@ public class DayPicker extends FrameLayout { // causes the month to transition when two full weeks of a month are // visible when scrolling up, and when the first day in a month reaches // the top of the screen when scrolling down. + int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0; if (mIsScrollingUp) { child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset); } else if (offset != 0) { @@ -712,8 +728,9 @@ public class DayPicker extends FrameLayout { throw new IllegalArgumentException("fromDate: " + mRangeStartDate.getTime() + " does not precede toDate: " + toDate.getTime()); } + int fromDateDayOfWeek = mRangeStartDate.get(Calendar.DAY_OF_WEEK); - long diff = (fromDateDayOfWeek - toDate.getFirstDayOfWeek()) * MILLIS_IN_DAY; + long diff = (fromDateDayOfWeek - mFirstDayOfWeek) * MILLIS_IN_DAY; if (diff < 0) { diff = diff + MILLIS_IN_WEEK; } @@ -874,7 +891,16 @@ public class DayPicker extends FrameLayout { protected void init() { mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener()); mSelectedWeek = getWeeksDelta(mSelectedDay); - mTotalWeekCount = getWeeksDelta(mRangeEndDate); + + // make adjustment to fit the range last week with needed overflow + mTempCalendar.setTimeInMillis(mRangeEndDate.getTimeInMillis()); + mTempCalendar.setTimeZone(mRangeEndDate.getTimeZone()); + int diff = mFirstDayOfWeek - mRangeEndDate.get(Calendar.DAY_OF_WEEK); + if (diff < 0) { + diff += DAYS_PER_WEEK; + } + mTempCalendar.add(Calendar.DAY_OF_WEEK, diff); + mTotalWeekCount = getWeeksDelta(mTempCalendar); } /** @@ -892,7 +918,6 @@ public class DayPicker extends FrameLayout { mSelectedWeek = getWeeksDelta(mSelectedDay); mFocusMonth = mSelectedDay.get(Calendar.MONTH); notifyDataSetChanged(); - invalidate(); // Test } /** @@ -1004,9 +1029,12 @@ public class DayPicker extends FrameLayout { if (mGestureDetector.onTouchEvent(event)) { WeekView weekView = (WeekView) v; weekView.getDayFromLocation(event.getX(), mTempCalendar); - if (mTempCalendar.get(Calendar.YEAR) != 0) { - onDayTapped(mTempCalendar); + // it is possible that the touched day is outside the valid range + // we draw whole weeks but range end can fall not on the week end + if (mTempCalendar.before(mRangeStartDate) || mTempCalendar.after(mRangeEndDate)) { + return true; } + onDayTapped(mTempCalendar); return true; } return false; @@ -1019,6 +1047,7 @@ public class DayPicker extends FrameLayout { */ protected void onDayTapped(Calendar day) { setSelectedDay(day); + setMonthDisplayed(day); } /** @@ -1244,8 +1273,8 @@ public class DayPicker extends FrameLayout { mNumCells = mShowWeekNumber ? mWeekDayCount + 1 : mWeekDayCount; } mWeek = ((int[]) params.get(VIEW_PARAMS_WEEK))[0]; - mTempCalendar.clear(); - mTempCalendar.set(1900, 0, 1); + mTempCalendar.setTimeInMillis(mRangeStartDate.getTimeInMillis()); + mTempCalendar.setTimeZone(mRangeStartDate.getTimeZone()); mTempCalendar.add(Calendar.WEEK_OF_YEAR, mWeek); if (params.containsKey(VIEW_PARAMS_WEEK_START)) { mTempCalendar.setFirstDayOfWeek(((int[]) params.get(VIEW_PARAMS_WEEK_START))[0]); @@ -1277,7 +1306,12 @@ public class DayPicker extends FrameLayout { for (; i < mNumCells; i++) { mFocusDay[i] = (mTempCalendar.get(Calendar.MONTH) == focusMonth); - mDayNumbers[i] = Integer.toString(mTempCalendar.get(Calendar.DAY_OF_MONTH)); + // do not draw dates outside the valid range to avoid user confusion + if (mTempCalendar.before(mRangeStartDate) || mTempCalendar.after(mRangeEndDate)) { + mDayNumbers[i] = ""; + } else { + mDayNumbers[i] = Integer.toString(mTempCalendar.get(Calendar.DAY_OF_MONTH)); + } mTempCalendar.add(Calendar.DAY_OF_MONTH, 1); } // We do one extra add at the end of the loop, if that pushed us to diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 8c22f97..a236d27 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -1189,9 +1189,9 @@ public class NumberPicker extends LinearLayout { */ private int getWrappedSelectorIndex(int selectorIndex) { if (selectorIndex > mEnd) { - return mStart + (selectorIndex - mEnd) % (mEnd - mStart); + return mStart + (selectorIndex - mEnd) % (mEnd - mStart) - 1; } else if (selectorIndex < mStart) { - return mEnd - (mStart - selectorIndex) % (mEnd - mStart); + return mEnd - (mStart - selectorIndex) % (mEnd - mStart) + 1; } return selectorIndex; } |