DatePickerCalendarDelegate.java revision f7aa9251d091d0e52e879a8a92bd38228e58efd9
1bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/*
2bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Copyright (C) 2014 The Android Open Source Project
3bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *
4bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
5bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * you may not use this file except in compliance with the License.
6bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * You may obtain a copy of the License at
7bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *
8bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
9bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *
10bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
11bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
12bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * See the License for the specific language governing permissions and
14bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * limitations under the License.
15bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */
16bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
17bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Megliopackage android.widget;
18bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.annotation.Nullable;
20bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.Context;
21bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.ColorStateList;
22bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.Configuration;
23bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.Resources;
24bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.TypedArray;
25bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcel;
26bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcelable;
27bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateFormat;
28bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateUtils;
29bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.util.AttributeSet;
300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.util.StateSet;
31bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.HapticFeedbackConstants;
32bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.LayoutInflater;
33bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.View;
340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.View.OnClickListener;
350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.ViewGroup;
36bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.accessibility.AccessibilityEvent;
370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.widget.DayPickerView.OnDaySelectedListener;
380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.widget.YearPickerView.OnYearSelectedListener;
39bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
40bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport com.android.internal.R;
41bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
42bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.text.SimpleDateFormat;
43bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Calendar;
44bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Locale;
45bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
46bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/**
47bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * A delegate for picking up a date (day / month / year).
48bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */
490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteclass DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate {
500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    private static final int USE_LOCALE = 0;
51bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
52bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int UNINITIALIZED = -1;
530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private static final int VIEW_MONTH_DAY = 0;
540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private static final int VIEW_YEAR = 1;
55bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
56bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DEFAULT_START_YEAR = 1900;
57bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DEFAULT_END_YEAR = 2100;
58bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
59bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int ANIMATION_DURATION = 300;
60bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
6160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private static final int[] ATTRS_TEXT_COLOR = new int[] {
6260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            com.android.internal.R.attr.textColor};
6360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private static final int[] ATTRS_DISABLED_ALPHA = new int[] {
640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            com.android.internal.R.attr.disabledAlpha};
65bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private SimpleDateFormat mYearFormat;
670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private SimpleDateFormat mMonthDayFormat;
687119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    // Top-level container.
700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private ViewGroup mContainer;
717119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    // Header views.
730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private TextView mHeaderYear;
740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private TextView mHeaderMonthDay;
757119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    // Picker views.
770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private ViewAnimator mAnimator;
78bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private DayPickerView mDayPickerView;
79bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private YearPickerView mYearPickerView;
80bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
81bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // Accessibility strings.
82bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mSelectDay;
83bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mSelectYear;
84bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
85bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private DatePicker.OnDateChangedListener mDateChangedListener;
86bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
87bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int mCurrentView = UNINITIALIZED;
88bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
89452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette    private final Calendar mCurrentDate;
90452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette    private final Calendar mTempDate;
91452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette    private final Calendar mMinDate;
92452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette    private final Calendar mMaxDate;
93bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
940a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    private int mFirstDayOfWeek = USE_LOCALE;
950a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
963053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs,
97bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
98bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        super(delegator, context);
99bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final Locale locale = mCurrentLocale;
101452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette        mCurrentDate = Calendar.getInstance(locale);
102452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette        mTempDate = Calendar.getInstance(locale);
103452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette        mMinDate = Calendar.getInstance(locale);
104452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette        mMaxDate = Calendar.getInstance(locale);
105bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
10649e6c4adbfad8cac28a0c7c68918b443a64a07d8You Kim        mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
10749e6c4adbfad8cac28a0c7c68918b443a64a07d8You Kim        mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
108bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
10960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final Resources res = mDelegator.getResources();
110bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final TypedArray a = mContext.obtainStyledAttributes(attrs,
111bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.styleable.DatePicker, defStyleAttr, defStyleRes);
112bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
113bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Context.LAYOUT_INFLATER_SERVICE);
114bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int layoutResourceId = a.getResourceId(
1150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                R.styleable.DatePicker_internalLayout, R.layout.date_picker_material);
1160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up and attach container.
118f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mContainer = (ViewGroup) inflater.inflate(layoutResourceId, mDelegator, false);
119f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mDelegator.addView(mContainer);
120bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1210ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up header views.
1220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final ViewGroup header = (ViewGroup) mContainer.findViewById(R.id.date_picker_header);
1230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mHeaderYear = (TextView) header.findViewById(R.id.date_picker_header_year);
1240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mHeaderYear.setOnClickListener(mOnHeaderClickListener);
1250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mHeaderMonthDay = (TextView) header.findViewById(R.id.date_picker_header_date);
1260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mHeaderMonthDay.setOnClickListener(mOnHeaderClickListener);
127ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette
1280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // For the sake of backwards compatibility, attempt to extract the text
1290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // color from the header month text appearance. If it's set, we'll let
1300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // that override the "real" header text color.
1310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        ColorStateList headerTextColor = null;
132bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        @SuppressWarnings("deprecation")
1340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int monthHeaderTextAppearance = a.getResourceId(
1354e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_headerMonthTextAppearance, 0);
1360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (monthHeaderTextAppearance != 0) {
1370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final TypedArray textAppearance = mContext.obtainStyledAttributes(null,
1380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    ATTRS_TEXT_COLOR, 0, monthHeaderTextAppearance);
1390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final ColorStateList legacyHeaderTextColor = textAppearance.getColorStateList(0);
1400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            headerTextColor = applyLegacyColorFixes(legacyHeaderTextColor);
1410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            textAppearance.recycle();
142bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
14360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
1440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (headerTextColor == null) {
1450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            headerTextColor = a.getColorStateList(R.styleable.DatePicker_headerTextColor);
14660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        }
14760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
1480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (headerTextColor != null) {
1490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            mHeaderYear.setTextColor(headerTextColor);
1500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            mHeaderMonthDay.setTextColor(headerTextColor);
15160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        }
152bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up header background, if available.
1540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (a.hasValueOrEmpty(R.styleable.DatePicker_headerBackground)) {
1550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            header.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground));
1560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
1570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
15860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        a.recycle();
15960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
1600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up picker container.
1610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mAnimator = (ViewAnimator) mContainer.findViewById(R.id.animator);
1620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up day picker view.
1640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mDayPickerView = (DayPickerView) mAnimator.findViewById(R.id.date_picker_day_picker);
165e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
1664612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
1674612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
1684612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
169e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
17050eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette
1710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up year picker view.
1720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker);
1732a90fa6d94b7d31e997493d2d0601e5129ec7c3eAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
1740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mYearPickerView.setDate(mCurrentDate.getTimeInMillis());
1750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener);
1764e5168fae43e783a35c5bc731e500196005268fbAlan Viverette
1770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set up content descriptions.
178bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectDay = res.getString(R.string.select_day);
179bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectYear = res.getString(R.string.select_year);
180bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Initialize for current locale. This also initializes the date, so no
1820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // need to call onDateChanged.
1830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        onLocaleChanged(mCurrentLocale);
1840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        setCurrentView(VIEW_MONTH_DAY);
1860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    /**
1890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * The legacy text color might have been poorly defined. Ensures that it
1900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * has an appropriate activated state, using the selected state if one
1910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * exists or modifying the default text color otherwise.
1920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     *
1930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * @param color a legacy text color, or {@code null}
1940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * @return a color state list with an appropriate activated state, or
1950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     *         {@code null} if a valid activated state could not be generated
1960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
1970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Nullable
1980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private ColorStateList applyLegacyColorFixes(@Nullable ColorStateList color) {
1990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (color == null || color.hasState(R.attr.state_activated)) {
2000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            return color;
2010ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int activatedColor;
2040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int defaultColor;
2050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (color.hasState(R.attr.state_selected)) {
2060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            activatedColor = color.getColorForState(StateSet.get(
2070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_SELECTED), 0);
2080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            defaultColor = color.getColorForState(StateSet.get(
2090ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    StateSet.VIEW_STATE_ENABLED), 0);
2100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        } else {
2110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            activatedColor = color.getDefaultColor();
2120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // Generate a non-activated color using the disabled alpha.
2140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final TypedArray ta = mContext.obtainStyledAttributes(ATTRS_DISABLED_ALPHA);
2150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final float disabledAlpha = ta.getFloat(0, 0.30f);
2160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            defaultColor = multiplyAlphaComponent(activatedColor, disabledAlpha);
2170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2187119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (activatedColor == 0 || defaultColor == 0) {
2200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // We somehow failed to obtain the colors.
2210ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            return null;
2220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2237119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int[][] stateSet = new int[][] {{ R.attr.state_activated }, {}};
2250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int[] colors = new int[] { activatedColor, defaultColor };
2260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return new ColorStateList(stateSet, colors);
2270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
228bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
2290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int multiplyAlphaComponent(int color, float alphaMod) {
2300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int srcRgb = color & 0xFFFFFF;
2310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int srcAlpha = (color >> 24) & 0xFF;
2320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int dstAlpha = (int) (srcAlpha * alphaMod + 0.5f);
2330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return srcRgb | (dstAlpha << 24);
234bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
235bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
236bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
2370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * Listener called when the user selects a day in the day picker view.
2380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
2390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private final OnDaySelectedListener mOnDaySelectedListener = new OnDaySelectedListener() {
2400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        @Override
2410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        public void onDaySelected(DayPickerView view, Calendar day) {
2420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            mCurrentDate.setTimeInMillis(day.getTimeInMillis());
2430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            onDateChanged(true, true);
2440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    };
2460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    /**
2480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * Listener called when the user selects a year in the year picker view.
2490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
2500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private final OnYearSelectedListener mOnYearSelectedListener = new OnYearSelectedListener() {
2510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        @Override
2520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        public void onYearChanged(YearPickerView view, int year) {
2530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // If the newly selected month / year does not contain the
2540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // currently selected day number, change the selected day number
2550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // to the last day of the selected month or year.
2560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
2570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
2580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
2590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final int month = mCurrentDate.get(Calendar.MONTH);
2600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final int daysInMonth = getDaysInMonth(month, year);
2610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            if (day > daysInMonth) {
2620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
2630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            }
2640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            mCurrentDate.set(Calendar.YEAR, year);
2660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            onDateChanged(true, true);
2670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2680ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // Automatically switch to day picker.
2690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            setCurrentView(VIEW_MONTH_DAY);
2700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    };
2720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    /**
2740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * Listener called when the user clicks on a header item.
2750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
2760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private final OnClickListener mOnHeaderClickListener = new OnClickListener() {
2770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        @Override
2780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        public void onClick(View v) {
2790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            tryVibrate();
2800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            switch (v.getId()) {
2820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                case R.id.date_picker_header_year:
2830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    setCurrentView(VIEW_YEAR);
2840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    break;
2850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                case R.id.date_picker_header_date:
2860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    setCurrentView(VIEW_MONTH_DAY);
2870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    break;
2880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            }
2890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    };
2910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
2930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    protected void onLocaleChanged(Locale locale) {
2940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final TextView headerYear = mHeaderYear;
2950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (headerYear == null) {
2960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // Abort, we haven't initialized yet. This method will get called
2970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // again later after everything has been set up.
2980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            return;
299bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
300bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3010ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Update the date formatter.
3020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final String datePattern = DateFormat.getBestDateTimePattern(locale, "EMMMd");
3030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mMonthDayFormat = new SimpleDateFormat(datePattern, locale);
3040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mYearFormat = new SimpleDateFormat("y", locale);
305bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Update the header text.
3070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        onCurrentDateChanged(false);
3080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
309bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private void onCurrentDateChanged(boolean announce) {
3110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mHeaderYear == null) {
3120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // Abort, we haven't initialized yet. This method will get called
3130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // again later after everything has been set up.
3140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            return;
315bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
316bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final String year = mYearFormat.format(mCurrentDate.getTime());
3180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mHeaderYear.setText(year);
319bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final String monthDay = mMonthDayFormat.format(mCurrentDate.getTime());
3210ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mHeaderMonthDay.setText(monthDay);
322bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // TODO: This should use live regions.
324bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (announce) {
3250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final long millis = mCurrentDate.getTimeInMillis();
3260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
3270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            final String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
328bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mAnimator.announceForAccessibility(fullDateText);
329bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
330bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
331bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
332bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void setCurrentView(final int viewIndex) {
333bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (viewIndex) {
3340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            case VIEW_MONTH_DAY:
3350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
3360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
337bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
3380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    mHeaderMonthDay.setActivated(true);
3390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    mHeaderYear.setActivated(false);
3400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    mAnimator.setDisplayedChild(VIEW_MONTH_DAY);
341bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
342bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
343bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
344bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectDay);
345bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
3460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            case VIEW_YEAR:
3470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                mYearPickerView.setDate(mCurrentDate.getTimeInMillis());
3480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
349bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
3500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    mHeaderMonthDay.setActivated(false);
3510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    mHeaderYear.setActivated(true);
3520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                    mAnimator.setDisplayedChild(VIEW_YEAR);
353bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
354bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
355bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
356bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectYear);
357bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
358bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
359bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
360bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
361bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
362bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
363bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            DatePicker.OnDateChangedListener callBack) {
364bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
365bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, monthOfYear);
366bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
367e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
368e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        mDateChangedListener = callBack;
3690cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette
3700cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(false, false);
371bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
375bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
376bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
377bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
378e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3790cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(false, true);
380e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette    }
381e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3820cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette    private void onDateChanged(boolean fromUser, boolean callbackToClient) {
3830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int year = mCurrentDate.get(Calendar.YEAR);
3840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
3850cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        if (callbackToClient && mDateChangedListener != null) {
386e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
387e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
388e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
389e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        }
390e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
3920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mYearPickerView.setYear(year);
393e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        onCurrentDateChanged(fromUser);
395e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
396e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        if (fromUser) {
397e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            tryVibrate();
3989468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        }
399bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
400bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
401bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
402bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getYear() {
403bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.YEAR);
404bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
405bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
406bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
407bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMonth() {
408bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.MONTH);
409bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
410bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
411bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
412bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getDayOfMonth() {
413bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
414bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
415bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMinDate(long minDate) {
418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(minDate);
419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.before(mTempDate)) {
424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(minDate);
4250cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(false, true);
426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(minDate);
4284612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMinDate(minDate);
42950eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
433bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMinDate() {
434bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate;
435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
436bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMaxDate(long maxDate) {
439bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(maxDate);
440bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
443bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
444bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.after(mTempDate)) {
445bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(maxDate);
4460cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(false, true);
447bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
448bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(maxDate);
4494612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMaxDate(maxDate);
45050eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
451bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
452bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
453bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
454bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMaxDate() {
455bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate;
456bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
4590a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
4600a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mFirstDayOfWeek = firstDayOfWeek;
461e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
462e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
4630a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4640a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4650a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    @Override
466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getFirstDayOfWeek() {
4670a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (mFirstDayOfWeek != USE_LOCALE) {
4680a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mFirstDayOfWeek;
4690a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
470bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.getFirstDayOfWeek();
471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
472bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
473bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
474bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setEnabled(boolean enabled) {
475f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mContainer.setEnabled(enabled);
476f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mDayPickerView.setEnabled(enabled);
477f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mYearPickerView.setEnabled(enabled);
478f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mHeaderYear.setEnabled(enabled);
479f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        mHeaderMonthDay.setEnabled(enabled);
480bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
481bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
482bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
483bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean isEnabled() {
4840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return mContainer.isEnabled();
485bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public CalendarView getCalendarView() {
489f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette        throw new UnsupportedOperationException("Not supported by calendar-mode DatePicker");
490bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
491bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
492bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
493bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setCalendarViewShown(boolean shown) {
494bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getCalendarViewShown() {
499bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setSpinnersShown(boolean shown) {
504bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getSpinnersShown() {
509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onConfigurationChanged(Configuration newConfig) {
5140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        setCurrentLocale(newConfig.locale);
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Parcelable onSaveInstanceState(Parcelable superState) {
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int year = mCurrentDate.get(Calendar.YEAR);
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int month = mCurrentDate.get(Calendar.MONTH);
521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPosition = -1;
524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPositionOffset = -1;
525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
5260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mCurrentView == VIEW_MONTH_DAY) {
527bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mDayPickerView.getMostVisiblePosition();
5280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        } else if (mCurrentView == VIEW_YEAR) {
529bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mYearPickerView.getFirstVisiblePosition();
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPositionOffset = mYearPickerView.getFirstPositionOffset();
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
539816aa142023c75cf427401c21831193998bdf233Alan Viverette        final SavedState ss = (SavedState) state;
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
5410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // TODO: Move instance state into DayPickerView, YearPickerView.
542a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
543bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(ss.getMinDate());
544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(ss.getMaxDate());
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
5460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        onCurrentDateChanged(false);
547816aa142023c75cf427401c21831193998bdf233Alan Viverette
548816aa142023c75cf427401c21831193998bdf233Alan Viverette        final int currentView = ss.getCurrentView();
549816aa142023c75cf427401c21831193998bdf233Alan Viverette        setCurrentView(currentView);
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
551bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int listPosition = ss.getListPosition();
552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (listPosition != -1) {
553816aa142023c75cf427401c21831193998bdf233Alan Viverette            if (currentView == VIEW_MONTH_DAY) {
55478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette                mDayPickerView.setPosition(listPosition);
555816aa142023c75cf427401c21831193998bdf233Alan Viverette            } else if (currentView == VIEW_YEAR) {
5560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                final int listPositionOffset = ss.getListPositionOffset();
5570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                mYearPickerView.setSelectionFromTop(listPosition, listPositionOffset);
558bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
560bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
561bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
562bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
563bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
564bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        onPopulateAccessibilityEvent(event);
565bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return true;
566bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
567bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
568bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
569bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
570bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.getText().add(mCurrentDate.getTime().toString());
571bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
573a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn    public CharSequence getAccessibilityClassName() {
574a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn        return DatePicker.class.getName();
575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public static int getDaysInMonth(int month, int year) {
578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (month) {
579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JANUARY:
580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MARCH:
581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MAY:
582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JULY:
583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.AUGUST:
584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.OCTOBER:
585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.DECEMBER:
586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 31;
587bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.APRIL:
588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JUNE:
589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.SEPTEMBER:
590bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.NOVEMBER:
591bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 30;
592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.FEBRUARY:
593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return (year % 4 == 0) ? 29 : 28;
594bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            default:
595bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                throw new IllegalArgumentException("Invalid Month");
596bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
597bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
5990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private void tryVibrate() {
600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
603e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    /**
604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Class for managing state storing/restoring.
605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static class SavedState extends View.BaseSavedState {
607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedYear;
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedMonth;
609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedDay;
610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMinDate;
611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMaxDate;
612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mCurrentView;
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPosition;
614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPositionOffset;
615bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
616bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link DatePicker#onSaveInstanceState()}
618bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
619bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcelable superState, int year, int month, int day,
620bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                long minDate, long maxDate, int currentView, int listPosition,
621bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                int listPositionOffset) {
622bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(superState);
623bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = year;
624bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = month;
625bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = day;
626bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = minDate;
627bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = maxDate;
628bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = currentView;
629bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = listPosition;
630bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = listPositionOffset;
631bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
632bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
633bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
634bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link #CREATOR}
635bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
636bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcel in) {
637bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(in);
638bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = in.readInt();
639bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = in.readInt();
640bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = in.readInt();
641bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = in.readLong();
642bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = in.readLong();
643bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = in.readInt();
644bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = in.readInt();
645bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = in.readInt();
646bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
647bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
648bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @Override
649bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public void writeToParcel(Parcel dest, int flags) {
650bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super.writeToParcel(dest, flags);
651bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedYear);
652bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedMonth);
653bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedDay);
654bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMinDate);
655bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMaxDate);
656bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mCurrentView);
657bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPosition);
658bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPositionOffset);
659bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
660bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
661bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedDay() {
662bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedDay;
663bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
664bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
665bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedMonth() {
666bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedMonth;
667bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
668bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
669bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedYear() {
670bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedYear;
671bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
672bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
673bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMinDate() {
674bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMinDate;
675bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
676bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
677bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMaxDate() {
678bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMaxDate;
679bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
680bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
681bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getCurrentView() {
682bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mCurrentView;
683bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
684bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
685bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPosition() {
686bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPosition;
687bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
688bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
689bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPositionOffset() {
690bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPositionOffset;
691bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
692bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
693bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @SuppressWarnings("all")
694bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // suppress unused and hiding
695bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
696bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
697bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
698bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState(in);
699bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
700bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
701bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState[] newArray(int size) {
702bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState[size];
703bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
704bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        };
705bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
706bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio}
707