summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2011-01-24 02:13:36 -0800
committerSvetoslav Ganov <svetoslavganov@google.com>2011-01-24 05:21:32 -0800
commit156f20919b3d5f298f8851215adbf65f8b4dc61b (patch)
tree6a39f9a3388a143ef7ca603453550057e30b7ba9 /core
parenta6ce081970a78233ba6b9792149ee5f1390cba7b (diff)
downloadframeworks_base-156f20919b3d5f298f8851215adbf65f8b4dc61b.zip
frameworks_base-156f20919b3d5f298f8851215adbf65f8b4dc61b.tar.gz
frameworks_base-156f20919b3d5f298f8851215adbf65f8b4dc61b.tar.bz2
DatePicker is picking the wrong date
bug:3375074 1. The logic for updating the higher rank fields on wrapping of lower rank ones was incorrect. Updated that logic. 2. On reaching the min/max date the spinners did not stop when reaching that date. Now spinners stop at min/max. 3. Fixed a couple of edge case bugs while setting the the min and max dates of the DatePicker on the fly. 4. Restricted the scrolling/flinging to end at the min and max dates. Change-Id: Ibb588ea2cf951cf8d50328bbfbe7ebdad7ee8067
Diffstat (limited to 'core')
-rw-r--r--core/java/android/widget/CalendarView.java19
-rw-r--r--core/java/android/widget/DatePicker.java193
-rw-r--r--core/java/android/widget/NumberPicker.java4
3 files changed, 122 insertions, 94 deletions
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 7ef61a8..899e872 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -440,11 +440,18 @@ public class CalendarView extends FrameLayout {
return;
}
mMinDate.setTimeInMillis(minDate);
+ // make sure the current date is not earlier than
+ // the new min date since the latter is used for
+ // calculating the indices in the adapter thus
+ // avoiding out of bounds error
+ Calendar date = mAdapter.mSelectedDate;
+ if (date.before(mMinDate)) {
+ mAdapter.setSelectedDay(mMinDate);
+ }
// reinitialize the adapter since its range depends on min date
mAdapter.init();
- Calendar date = mAdapter.mSelectedDate;
if (date.before(mMinDate)) {
- setDate(mMinDate.getTimeInMillis());
+ setDate(mTempDate.getTimeInMillis());
} else {
// we go to the current date to force the ListView to query its
// adapter for the shown views since we have changed the adapter
@@ -753,7 +760,13 @@ public class CalendarView extends FrameLayout {
mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
setMonthDisplayed(mFirstDayOfMonth);
- position = getWeeksSinceMinDate(mFirstDayOfMonth);
+
+ // the earliest time we can scroll to is the min date
+ if (mFirstDayOfMonth.before(mMinDate)) {
+ position = 0;
+ } else {
+ position = getWeeksSinceMinDate(mFirstDayOfMonth);
+ }
mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
if (animate) {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index f1786e2..ea868a6 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -34,6 +34,7 @@ import android.widget.NumberPicker.OnValueChangeListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
@@ -156,8 +157,34 @@ public class DatePicker extends FrameLayout {
OnValueChangeListener onChangeListener = new OnValueChangeListener() {
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- updateDate(mYearSpinner.getValue(), mMonthSpinner.getValue(), mDaySpinner
- .getValue());
+ mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
+ // take care of wrapping of days and months to update greater fields
+ if (picker == mDaySpinner) {
+ int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
+ if (oldVal == maxDayOfMonth && newVal == 1) {
+ mTempDate.add(Calendar.DAY_OF_MONTH, 1);
+ } else if (oldVal == 1 && newVal == maxDayOfMonth) {
+ mTempDate.add(Calendar.DAY_OF_MONTH, -1);
+ } else {
+ mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
+ }
+ } else if (picker == mMonthSpinner) {
+ if (oldVal == 11 && newVal == 0) {
+ mTempDate.add(Calendar.MONTH, 1);
+ } else if (oldVal == 0 && newVal == 11) {
+ mTempDate.add(Calendar.MONTH, -1);
+ } else {
+ mTempDate.add(Calendar.MONTH, newVal - oldVal);
+ }
+ } else if (picker == mYearSpinner) {
+ mTempDate.set(Calendar.YEAR, newVal);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ // now set the date to the adjusted one
+ setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
+ mTempDate.get(Calendar.DAY_OF_MONTH));
+ notifyDateChanged();
}
};
@@ -167,7 +194,8 @@ public class DatePicker extends FrameLayout {
mCalendarView = (CalendarView) findViewById(R.id.calendar_view);
mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
- updateDate(year, month, monthDay);
+ setDate(year, month, monthDay);
+ notifyDateChanged();
}
});
@@ -260,10 +288,12 @@ public class DatePicker extends FrameLayout {
return;
}
mMinDate.setTimeInMillis(minDate);
- mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
- mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
mCalendarView.setMinDate(minDate);
- updateSpinners(mYearSpinner.getValue(), mMonthSpinner.getValue(), mDaySpinner.getValue());
+ if (mCurrentDate.before(mMinDate)) {
+ mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+ updateCalendarView();
+ }
+ updateSpinners();
}
/**
@@ -294,10 +324,12 @@ public class DatePicker extends FrameLayout {
return;
}
mMaxDate.setTimeInMillis(maxDate);
- mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
- mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
mCalendarView.setMaxDate(maxDate);
- updateSpinners(mYearSpinner.getValue(), mMonthSpinner.getValue(), mDaySpinner.getValue());
+ if (mCurrentDate.after(mMaxDate)) {
+ mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+ updateCalendarView();
+ }
+ updateSpinners();
}
@Override
@@ -433,13 +465,11 @@ public class DatePicker extends FrameLayout {
* @param dayOfMonth The day of the month.
*/
public void updateDate(int year, int month, int dayOfMonth) {
- if (mCurrentDate.get(Calendar.YEAR) != year
- || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
- || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month) {
- updateSpinners(year, month, dayOfMonth);
- updateCalendarView();
- notifyDateChanged();
+ if (!isNewDate(year, month, dayOfMonth)) {
+ return;
}
+ setDate(year, month, dayOfMonth);
+ notifyDateChanged();
}
// Override so we are in complete control of save / restore for this widget.
@@ -451,15 +481,14 @@ public class DatePicker extends FrameLayout {
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
- return new SavedState(superState, mYearSpinner.getValue(), mMonthSpinner.getValue(),
- mDaySpinner.getValue());
+ return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
- updateSpinners(ss.mYear, ss.mMonth, ss.mDay);
+ setDate(ss.mYear, ss.mMonth, ss.mDay);
}
/**
@@ -474,10 +503,7 @@ public class DatePicker extends FrameLayout {
*/
public void init(int year, int monthOfYear, int dayOfMonth,
OnDateChangedListener onDateChangedListener) {
- // make sure there is no callback
- mOnDateChangedListener = null;
- updateDate(year, monthOfYear, dayOfMonth);
- // register the callback after updating the date
+ setDate(year, monthOfYear, dayOfMonth);
mOnDateChangedListener = onDateChangedListener;
}
@@ -514,104 +540,94 @@ public class DatePicker extends FrameLayout {
}
}
- /**
- * Updates the spinners with the given <code>year</code>, <code>month</code>
- * , and <code>dayOfMonth</code>. If the provided values designate an
- * inconsistent date the values are normalized before updating the spinners.
- */
- private void updateSpinners(int year, int month, int dayOfMonth) {
- // compute the deltas before modifying the current date
- int deltaMonths = getDelataMonth(month);
- int deltaDays = getDelataDayOfMonth(dayOfMonth);
- mCurrentDate.set(Calendar.YEAR, year);
- mCurrentDate.add(Calendar.MONTH, deltaMonths);
- mCurrentDate.add(Calendar.DAY_OF_MONTH, deltaDays);
+ private boolean isNewDate(int year, int month, int dayOfMonth) {
+ return (mCurrentDate.get(Calendar.YEAR) != year
+ || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
+ || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
+ }
+ private void setDate(int year, int month, int dayOfMonth) {
+ mCurrentDate.set(year, month, dayOfMonth);
if (mCurrentDate.before(mMinDate)) {
mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
} else if (mCurrentDate.after(mMaxDate)) {
mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
}
-
- mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
- mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
- mDaySpinner.setMinValue(1);
- mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
- mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+ updateSpinners();
+ updateCalendarView();
}
- /**
- * @return The delta days of moth from the current date and the given
- * <code>dayOfMonth</code>.
- */
- private int getDelataDayOfMonth(int dayOfMonth) {
- int prevDayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
- if (prevDayOfMonth == dayOfMonth) {
- return 0;
- }
- int maxDayOfMonth = mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH);
- if (dayOfMonth == 1 && prevDayOfMonth == maxDayOfMonth) {
- return 1;
- }
- if (dayOfMonth == maxDayOfMonth && prevDayOfMonth == 1) {
- return -1;
+ private void updateSpinners() {
+ // set the spinner ranges respecting the min and max dates
+ if (mCurrentDate.equals(mMinDate)) {
+ mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+ mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
+ mDaySpinner.setWrapSelectorWheel(false);
+ mMonthSpinner.setDisplayedValues(null);
+ mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
+ mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
+ mMonthSpinner.setWrapSelectorWheel(false);
+ } else if (mCurrentDate.equals(mMaxDate)) {
+ mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
+ mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+ mDaySpinner.setWrapSelectorWheel(false);
+ mMonthSpinner.setDisplayedValues(null);
+ mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
+ mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
+ mMonthSpinner.setWrapSelectorWheel(false);
+ } else {
+ mDaySpinner.setMinValue(1);
+ mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
+ mDaySpinner.setWrapSelectorWheel(true);
+ mMonthSpinner.setDisplayedValues(null);
+ mMonthSpinner.setMinValue(0);
+ mMonthSpinner.setMaxValue(11);
+ mMonthSpinner.setWrapSelectorWheel(true);
}
- return dayOfMonth - prevDayOfMonth;
- }
- /**
- * @return The delta months from the current date and the given
- * <code>month</code>.
- */
- private int getDelataMonth(int month) {
- int prevMonth = mCurrentDate.get(Calendar.MONTH);
- if (prevMonth == month) {
- return 0;
- }
- if (month == 0 && prevMonth == 11) {
- return 1;
- }
- if (month == 11 && prevMonth == 0) {
- return -1;
- }
- return month - prevMonth;
+ // make sure the month names are a zero based array
+ // with the months in the month spinner
+ String[] displayedValues = Arrays.copyOfRange(getShortMonths(),
+ mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
+ mMonthSpinner.setDisplayedValues(displayedValues);
+
+ // year spinner range does not change based on the current date
+ mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
+ mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
+ mYearSpinner.setWrapSelectorWheel(false);
+
+ // set the spinner values
+ mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
+ mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
+ mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
}
/**
- * Updates the calendar view with the given year, month, and day selected by
- * the number spinners.
+ * Updates the calendar view with the current date.
*/
private void updateCalendarView() {
- mTempDate.setTimeInMillis(mCalendarView.getDate());
- if (mTempDate.get(Calendar.YEAR) != mYearSpinner.getValue()
- || mTempDate.get(Calendar.MONTH) != mMonthSpinner.getValue()
- || mTempDate.get(Calendar.DAY_OF_MONTH) != mDaySpinner.getValue()) {
- mTempDate.clear();
- mTempDate.set(mYearSpinner.getValue(), mMonthSpinner.getValue(),
- mDaySpinner.getValue());
- mCalendarView.setDate(mTempDate.getTimeInMillis(), false, false);
- }
+ mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
}
/**
* @return The selected year.
*/
public int getYear() {
- return mYearSpinner.getValue();
+ return mCurrentDate.get(Calendar.YEAR);
}
/**
* @return The selected month.
*/
public int getMonth() {
- return mMonthSpinner.getValue();
+ return mCurrentDate.get(Calendar.MONTH);
}
/**
* @return The selected day of month.
*/
public int getDayOfMonth() {
- return mDaySpinner.getValue();
+ return mCurrentDate.get(Calendar.DAY_OF_MONTH);
}
/**
@@ -619,8 +635,7 @@ public class DatePicker extends FrameLayout {
*/
private void notifyDateChanged() {
if (mOnDateChangedListener != null) {
- mOnDateChangedListener.onDateChanged(DatePicker.this, mYearSpinner.getValue(),
- mMonthSpinner.getValue(), mDaySpinner.getValue());
+ mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(), getDayOfMonth());
}
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 08db207..c5161bc 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -917,6 +917,8 @@ public class NumberPicker extends LinearLayout {
// force the selector indices array to be reinitialized
mSelectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] = Integer.MAX_VALUE;
mWrapSelectorWheel = wrapSelector;
+ // force redraw since we might look different
+ updateIncrementAndDecrementButtonsVisibilityState();
}
}
@@ -972,7 +974,6 @@ public class NumberPicker extends LinearLayout {
setWrapSelectorWheel(wrapSelectorWheel);
resetSelectorWheelIndices();
updateInputTextView();
- updateIncrementAndDecrementButtonsVisibilityState();
}
/**
@@ -1004,7 +1005,6 @@ public class NumberPicker extends LinearLayout {
setWrapSelectorWheel(wrapSelectorWheel);
resetSelectorWheelIndices();
updateInputTextView();
- updateIncrementAndDecrementButtonsVisibilityState();
}
/**