Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33322052 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "DatePicker is picking the wrong date" into honeycomb

parents 1914971c 156f2091
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -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);

            // 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) {
+104 −89
Original line number Diff line number Diff line
@@ -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());
        }
        updateSpinners();
        updateCalendarView();
    }

        mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
        mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
    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.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
            mDaySpinner.setWrapSelectorWheel(true);
            mMonthSpinner.setDisplayedValues(null);
            mMonthSpinner.setMinValue(0);
            mMonthSpinner.setMaxValue(11);
            mMonthSpinner.setWrapSelectorWheel(true);
        }

    /**
     * @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;
        }
        return dayOfMonth - prevDayOfMonth;
    }
        // 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);

    /**
     * @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;
        // 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());
        }
    }

+2 −2
Original line number Diff line number Diff line
@@ -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();
    }

    /**