DatePicker.java revision a67d9095b7731df3a6ae3f45738a2980151fd1af
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viveretteimport android.annotation.Nullable;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.Widget;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
22f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport android.content.res.Configuration;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
26e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.text.TextUtils;
27e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kimimport android.text.InputType;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.DateFormat;
29dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport android.text.format.DateUtils;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
31e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.util.Log;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
34d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganovimport android.view.View;
358a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
368a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
37a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganovimport android.view.inputmethod.EditorInfo;
386304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganovimport android.view.inputmethod.InputMethodManager;
39cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganovimport android.widget.NumberPicker.OnValueChangeListener;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport com.android.internal.R;
42f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
43949e9df25bccb736675f950591d3a286ae4052fcElliott Hughesimport java.text.DateFormatSymbols;
44e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.text.ParseException;
4503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischerimport java.text.SimpleDateFormat;
46156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganovimport java.util.Arrays;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar;
48dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport java.util.Locale;
49e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.util.TimeZone;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51659f145278ffd85f934a435dbec47ead685caf59Elliott Hughesimport libcore.icu.ICU;
52659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
54e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * This class is a widget for selecting a date. The date can be selected by a
55e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * year, month, and day spinners or a {@link CalendarView}. The set of spinners
56e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * and the calendar view are automatically synchronized. The client can
57e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * customize whether only the spinners, or only the calendar view, or both to be
58e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * displayed. Also the minimal and maximal date from which dates to be selected
59e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * can be customized.
6050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * <p>
614c359b76f9a030f92a302ba74a528faa170bad4eScott Main * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
624c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide.
6350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * </p>
64e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p>
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}.
66e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * </p>
67e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov *
68e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_startYear
69e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_endYear
70e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_maxDate
71e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_minDate
72e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_spinnersShown
73e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_calendarViewShown
74ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette * @attr ref android.R.styleable#DatePicker_dayOfWeekBackground
7560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_dayOfWeekTextAppearance
76ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette * @attr ref android.R.styleable#DatePicker_headerBackground
7760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerMonthTextAppearance
7860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerDayOfMonthTextAppearance
7960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerYearTextAppearance
8060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_yearListItemTextAppearance
8160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_yearListSelectorColor
82bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * @attr ref android.R.styleable#DatePicker_calendarTextColor
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout {
86e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    private static final String LOG_TAG = DatePicker.class.getSimpleName();
87e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
883053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static final int MODE_SPINNER = 1;
893053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static final int MODE_CALENDAR = 2;
903053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase
9160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private final DatePickerDelegate mDelegate;
92bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
94e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * The callback used to indicate the user changes\d the date.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDateChangedListener {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
99e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         * Called upon a date change.
100e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         *
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param view The view associated with this listener.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param year The year that was set.
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param monthOfYear The month that was set (0-11) for compatibility
10450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         *            with {@link java.util.Calendar}.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dayOfMonth The day of the month that was set.
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context, AttributeSet attrs) {
1154243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov        this(context, attrs, R.attr.datePickerStyle);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
118617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
119617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
120617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
121617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
122617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
123617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
12660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                defStyleAttr, defStyleRes);
127518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        final int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
1280a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
129bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        a.recycle();
130bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1313053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        switch (mode) {
1323053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_CALENDAR:
1333053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1343053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
1353053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_SPINNER:
1363053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            default:
1373053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1383053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
139bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
1400a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
1410a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek != 0) {
1420a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            setFirstDayOfWeek(firstDayOfWeek);
1430a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
144bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
145bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1463053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
147bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1483053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerSpinnerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
149bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
150bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1513053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs,
152bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1533053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr,
154bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                defStyleRes);
155bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
156bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
157bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
158039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * Initialize the state. If the provided values designate an inconsistent
159039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * date the values are normalized before updating the spinners.
160039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
161039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The initial year.
162039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param monthOfYear The initial month <strong>starting from zero</strong>.
163039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The initial day of the month.
164039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param onDateChangedListener How user is notified date is changed by
165039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *            user, can be null.
166039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
167039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
168039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                     OnDateChangedListener onDateChangedListener) {
169039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
170039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
17113427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov
172039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
173bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Update the current date.
174039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
175039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The year.
176039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param month The month which is <strong>starting from zero</strong>.
177039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The day of the month.
178039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
179039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
180039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.updateDate(year, month, dayOfMonth);
181039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
182e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
183039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
184039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected year.
185039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
186039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getYear() {
187039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getYear();
188039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
1893fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
190039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
191039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected month.
192039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
193039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getMonth() {
194039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getMonth();
195039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
1964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
197039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
198039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected day of month.
199039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
200039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getDayOfMonth() {
201039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getDayOfMonth();
202e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
203e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
204e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
205e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the minimal date supported by this {@link DatePicker} in
206e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
207e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
208e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
209e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default minimal date is 01/01/1900.
210e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
211e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
212e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The minimal supported date.
213e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
214e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMinDate() {
215bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMinDate().getTimeInMillis();
216e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
217e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
218e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
219e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the minimal date supported by this {@link NumberPicker} in
220e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
221e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
222e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
223e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param minDate The minimal supported date.
224e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
225e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMinDate(long minDate) {
226039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMinDate(minDate);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
22928104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    /**
230e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the maximal date supported by this {@link DatePicker} in
231e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
232e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
233e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
234e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default maximal date is 12/31/2100.
23528104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     * <p>
23628104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     *
237e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The maximal supported date.
238e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
239e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMaxDate() {
240bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMaxDate().getTimeInMillis();
241e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
242e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
243e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
244e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the maximal date supported by this {@link DatePicker} in
245e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
246e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
247e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
248e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param maxDate The maximal supported date.
24928104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     */
250e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMaxDate(long maxDate) {
251039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMaxDate(maxDate);
25228104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    }
25328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov
254518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    /**
255518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * Sets the callback that indicates the current date is valid.
256518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     *
257518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @param callback the callback, may be null
258518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @hide
259518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     */
260518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public void setValidationCallback(@Nullable ValidationCallback callback) {
261518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        mDelegate.setValidationCallback(callback);
262518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    }
263518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setEnabled(boolean enabled) {
266039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        if (mDelegate.isEnabled() == enabled) {
26751c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov            return;
26851c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setEnabled(enabled);
270039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setEnabled(enabled);
27151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    }
27251c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov
27351c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    @Override
27451c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    public boolean isEnabled() {
275039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.isEnabled();
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2788a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    @Override
2793fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
280039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.dispatchPopulateAccessibilityEvent(event);
2813fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    }
2823fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
2833fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    @Override
284736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
285736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        super.onPopulateAccessibilityEvent(event);
286039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onPopulateAccessibilityEvent(event);
2878a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    }
2888a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov
289f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    @Override
2908a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
2918a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityEvent(event);
292039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onInitializeAccessibilityEvent(event);
2938a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
2948a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
2958a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
2968a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
2978a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityNodeInfo(info);
298039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onInitializeAccessibilityNodeInfo(info);
2998a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3008a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
3018a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
302f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    protected void onConfigurationChanged(Configuration newConfig) {
303f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        super.onConfigurationChanged(newConfig);
304039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onConfigurationChanged(newConfig);
305f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    }
306f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
30750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
3080a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Sets the first day of week.
3090a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3100a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @param firstDayOfWeek The first day of the week conforming to the
3110a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *            {@link CalendarView} APIs.
3120a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3130a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3140a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3150a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3160a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3170a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3180a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3190a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3200a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3210a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3220a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
3230a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) {
3240a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7");
3250a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
3260a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
3270a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3280a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3290a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
3300a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Gets the first day of week.
3310a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3320a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @return The first day of the week conforming to the {@link CalendarView}
3330a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *         APIs.
3340a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3350a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3360a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3370a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3380a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3390a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3400a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3410a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3420a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3430a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3440a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public int getFirstDayOfWeek() {
3450a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        return mDelegate.getFirstDayOfWeek();
3460a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3470a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
349e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets whether the {@link CalendarView} is shown.
350e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
351e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return True if the calendar view is shown.
3525f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarView()
353e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
354e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getCalendarViewShown() {
355039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarViewShown();
356e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
357e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
358e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
3595f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * Gets the {@link CalendarView}.
3605f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     *
3615f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @return The calendar view.
3625f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarViewShown()
3635f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     */
3640a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public CalendarView getCalendarView() {
365039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarView();
3665f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    }
3675f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov
3685f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    /**
369e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the {@link CalendarView} is shown.
370e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
371e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param shown True if the calendar view is to be shown.
372e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
373e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setCalendarViewShown(boolean shown) {
374039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setCalendarViewShown(shown);
375e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
376e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
377e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
378e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets whether the spinners are shown.
379e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
380e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return True if the spinners are shown.
38150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
382e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getSpinnersShown() {
383039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getSpinnersShown();
384e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
385e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
386e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
387e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the spinners are shown.
388e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
389e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param shown True if the spinners are to be shown.
390e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
391e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setSpinnersShown(boolean shown) {
392039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setSpinnersShown(shown);
393039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
394039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
395039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
396039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
397d015e3454ec1271ba6e5e3e6f0e5f7459b8b09eaAlan Viverette        dispatchThawSelfOnly(container);
398039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
399039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
400039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
401039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected Parcelable onSaveInstanceState() {
402039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable superState = super.onSaveInstanceState();
403039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.onSaveInstanceState(superState);
404039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
405039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
406039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
407039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void onRestoreInstanceState(Parcelable state) {
408a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        BaseSavedState ss = (BaseSavedState) state;
409039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        super.onRestoreInstanceState(ss.getSuperState());
410039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onRestoreInstanceState(ss);
411e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
412e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
413e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
414039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate interface that defined the public API of the DatePicker. Allows different
415039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * DatePicker implementations. This would need to be implemented by the DatePicker delegates
416039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * for the real behavior.
417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
419f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
420039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    interface DatePickerDelegate {
421039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void init(int year, int monthOfYear, int dayOfMonth,
422039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                  OnDateChangedListener onDateChangedListener);
423f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
424039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void updateDate(int year, int month, int dayOfMonth);
425f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
426039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getYear();
427039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getMonth();
428039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getDayOfMonth();
429f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
4300a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        void setFirstDayOfWeek(int firstDayOfWeek);
4310a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        int getFirstDayOfWeek();
4320a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
433039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMinDate(long minDate);
434bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMinDate();
435949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
436039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMaxDate(long maxDate);
437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMaxDate();
438f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
439039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setEnabled(boolean enabled);
440039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean isEnabled();
441039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        CalendarView getCalendarView();
443039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
444039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setCalendarViewShown(boolean shown);
445039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getCalendarViewShown();
446039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
447039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setSpinnersShown(boolean shown);
448039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getSpinnersShown();
449039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
450518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void setValidationCallback(ValidationCallback callback);
451bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
452039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onConfigurationChanged(Configuration newConfig);
453039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
454039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable onSaveInstanceState(Parcelable superState);
455039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onRestoreInstanceState(Parcelable state);
456039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
457039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
458039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onPopulateAccessibilityEvent(AccessibilityEvent event);
459039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onInitializeAccessibilityEvent(AccessibilityEvent event);
460039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
461949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    }
462949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
463949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    /**
464039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * An abstract class which can be used as a start for DatePicker implementations
465f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    abstract static class AbstractDatePickerDelegate implements DatePickerDelegate {
467039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The delegator
468039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected DatePicker mDelegator;
469039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
470039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The context
471039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Context mContext;
472039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
473039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The current locale
474039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Locale mCurrentLocale;
475039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
476039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // Callbacks
477518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected OnDateChangedListener mOnDateChangedListener;
478518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected ValidationCallback mValidationCallback;
479039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
480bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
481039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
482039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
483039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
484039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialization based on locale
485039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
486f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        }
487f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
488039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
489039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (locale.equals(mCurrentLocale)) {
490039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
492039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentLocale = locale;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
494518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
495518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        @Override
496518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        public void setValidationCallback(ValidationCallback callback) {
497518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            mValidationCallback = callback;
498518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
499518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
500518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected void onValidationChanged(boolean valid) {
501518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            if (mValidationCallback != null) {
502518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette                mValidationCallback.onValidationChanged(valid);
503518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            }
504518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
508518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * A callback interface for updating input validity when the date picker
509518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * when included into a dialog.
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
513518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public static interface ValidationCallback {
514518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void onValidationChanged(boolean valid);
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
518039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate implementing the basic DatePicker
51950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
5203053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate {
521039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
522039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final String DATE_FORMAT = "MM/dd/yyyy";
523039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
524039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final int DEFAULT_START_YEAR = 1900;
525039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
526039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final int DEFAULT_END_YEAR = 2100;
527039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
528039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
529039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
530039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_SPINNERS_SHOWN = true;
531039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
532039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_ENABLED_STATE = true;
533039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
534039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final LinearLayout mSpinners;
535039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
536039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mDaySpinner;
537039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
538039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mMonthSpinner;
539039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
540039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mYearSpinner;
541039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
542039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mDaySpinnerInput;
543039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
544039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mMonthSpinnerInput;
545039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
546039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mYearSpinnerInput;
547039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
548039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final CalendarView mCalendarView;
549039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
550039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private String[] mShortMonths;
551039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
552039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
553039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
554039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private int mNumberOfMonths;
555039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
556039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mTempDate;
557039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
558039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mMinDate;
559039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
560039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mMaxDate;
561039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
562039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mCurrentDate;
563039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
564039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
565039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
5663053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        DatePickerSpinnerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
567039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                int defStyleAttr, int defStyleRes) {
568039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            super(delegator, context);
569039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
570039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
571039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
572039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
573039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialization based on locale
574039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
575039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
576039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
577039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.styleable.DatePicker, defStyleAttr, defStyleRes);
578039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
579039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    DEFAULT_SPINNERS_SHOWN);
580039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            boolean calendarViewShown = attributesArray.getBoolean(
581039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
582039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
583039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    DEFAULT_START_YEAR);
584039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
585039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
586039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
587039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int layoutResourceId = attributesArray.getResourceId(
588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    R.styleable.DatePicker_legacyLayout, R.layout.date_picker_legacy);
589039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            attributesArray.recycle();
590039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
591039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            LayoutInflater inflater = (LayoutInflater) context
592039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
593039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            inflater.inflate(layoutResourceId, mDelegator, true);
594039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
595039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            OnValueChangeListener onChangeListener = new OnValueChangeListener() {
596039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
597039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateInputState();
598039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
599039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    // take care of wrapping of days and months to update greater fields
600039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    if (picker == mDaySpinner) {
601039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
602039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        if (oldVal == maxDayOfMonth && newVal == 1) {
603039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, 1);
604039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else if (oldVal == 1 && newVal == maxDayOfMonth) {
605039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, -1);
606039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else {
607039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
608039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        }
609039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else if (picker == mMonthSpinner) {
610039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        if (oldVal == 11 && newVal == 0) {
611039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, 1);
612039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else if (oldVal == 0 && newVal == 11) {
613039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, -1);
614039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else {
615039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, newVal - oldVal);
616039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        }
617039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else if (picker == mYearSpinner) {
618039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mTempDate.set(Calendar.YEAR, newVal);
619039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else {
620039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        throw new IllegalArgumentException();
621039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    }
622039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    // now set the date to the adjusted one
623039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
624039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.get(Calendar.DAY_OF_MONTH));
625039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateSpinners();
626039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateCalendarView();
627039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    notifyDateChanged();
628039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
629039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            };
630039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
631039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners = (LinearLayout) mDelegator.findViewById(R.id.pickers);
632039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
633039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // calendar view day-picker
634039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView = (CalendarView) mDelegator.findViewById(R.id.calendar_view);
635039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
636039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
637039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    setDate(year, month, monthDay);
638039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateSpinners();
639039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    notifyDateChanged();
640039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
641039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            });
642039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
643039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // day
644039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner = (NumberPicker) mDelegator.findViewById(R.id.day);
645039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
646039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setOnLongPressUpdateInterval(100);
647039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setOnValueChangedListener(onChangeListener);
648039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
649039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
650039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // month
651039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner = (NumberPicker) mDelegator.findViewById(R.id.month);
652039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setMinValue(0);
653039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
654039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setDisplayedValues(mShortMonths);
655039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setOnLongPressUpdateInterval(200);
656039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setOnValueChangedListener(onChangeListener);
657039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
658039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
659039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // year
660039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner = (NumberPicker) mDelegator.findViewById(R.id.year);
661039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setOnLongPressUpdateInterval(100);
662039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setOnValueChangedListener(onChangeListener);
663039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
664039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
665039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // show only what the user required but make sure we
666039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // show something and the spinners have higher priority
667039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!spinnersShown && !calendarViewShown) {
668039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setSpinnersShown(true);
669039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
670039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setSpinnersShown(spinnersShown);
671039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setCalendarViewShown(calendarViewShown);
672039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
673039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
674039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the min date giving priority of the minDate over startYear
675039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.clear();
676039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!TextUtils.isEmpty(minDate)) {
677039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (!parseDate(minDate, mTempDate)) {
678039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.set(startYear, 0, 1);
679039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
680039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
681039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mTempDate.set(startYear, 0, 1);
682039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
683039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setMinDate(mTempDate.getTimeInMillis());
684039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
685039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the max date giving priority of the maxDate over endYear
686039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.clear();
687039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!TextUtils.isEmpty(maxDate)) {
688039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (!parseDate(maxDate, mTempDate)) {
689039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.set(endYear, 11, 31);
690039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
691039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
692039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mTempDate.set(endYear, 11, 31);
693039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
694039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setMaxDate(mTempDate.getTimeInMillis());
695039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
696039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialize to current date
697039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate.setTimeInMillis(System.currentTimeMillis());
698039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
699039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    .get(Calendar.DAY_OF_MONTH), null);
700039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
701039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // re-order the number spinners to match the current date format
702039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            reorderSpinners();
703039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
704039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // accessibility
705039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setContentDescriptions();
706039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
707039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // If not explicitly specified this view is important for accessibility.
708039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
709039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
710039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
711dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root        }
712dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root
713039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
714039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void init(int year, int monthOfYear, int dayOfMonth,
715039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                         OnDateChangedListener onDateChangedListener) {
716039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(year, monthOfYear, dayOfMonth);
717039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
718039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
719039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mOnDateChangedListener = onDateChangedListener;
720039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
722039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
723039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void updateDate(int year, int month, int dayOfMonth) {
724039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!isNewDate(year, month, dayOfMonth)) {
725039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
726039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
727039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(year, month, dayOfMonth);
728039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
729039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
730039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            notifyDateChanged();
731039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
733039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
734039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getYear() {
735039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.YEAR);
736039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
738039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
739039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getMonth() {
740039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.MONTH);
741039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
743039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
744039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getDayOfMonth() {
745039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.DAY_OF_MONTH);
746039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
747039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
748039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
7490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        public void setFirstDayOfWeek(int firstDayOfWeek) {
7500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            mCalendarView.setFirstDayOfWeek(firstDayOfWeek);
7510a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
7520a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
7530a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        @Override
7540a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        public int getFirstDayOfWeek() {
7550a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mCalendarView.getFirstDayOfWeek();
7560a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
7570a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
7580a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        @Override
759039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setMinDate(long minDate) {
760039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.setTimeInMillis(minDate);
761039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
762039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
763039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
764039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
765039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMinDate.setTimeInMillis(minDate);
766039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setMinDate(minDate);
767039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.before(mMinDate)) {
768039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
769039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                updateCalendarView();
770039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
771039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
772039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
773039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
774039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
775bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public Calendar getMinDate() {
776bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final Calendar minDate = Calendar.getInstance();
777bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            minDate.setTimeInMillis(mCalendarView.getMinDate());
778bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return minDate;
779039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
780039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
781039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
782039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setMaxDate(long maxDate) {
783039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.setTimeInMillis(maxDate);
784039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
785039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
786039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
787039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
788039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMaxDate.setTimeInMillis(maxDate);
789039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setMaxDate(maxDate);
790039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.after(mMaxDate)) {
791039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
792039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                updateCalendarView();
793039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
794039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
795039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
796039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
797039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
798bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public Calendar getMaxDate() {
799bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final Calendar maxDate = Calendar.getInstance();
800bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            maxDate.setTimeInMillis(mCalendarView.getMaxDate());
801bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return maxDate;
802039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
803039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
804039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
805039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setEnabled(boolean enabled) {
806039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setEnabled(enabled);
807039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setEnabled(enabled);
808039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setEnabled(enabled);
809039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setEnabled(enabled);
810039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mIsEnabled = enabled;
811039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
812039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
813039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
814039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean isEnabled() {
815039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mIsEnabled;
816039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
817039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
818039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
819039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public CalendarView getCalendarView() {
820039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCalendarView;
821039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
822039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
823039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
824039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setCalendarViewShown(boolean shown) {
825039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setVisibility(shown ? VISIBLE : GONE);
826039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
827039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
828039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
829039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean getCalendarViewShown() {
830039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return (mCalendarView.getVisibility() == View.VISIBLE);
831039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
832039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
833039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
834039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setSpinnersShown(boolean shown) {
835039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners.setVisibility(shown ? VISIBLE : GONE);
836039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
837039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
838039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
839039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean getSpinnersShown() {
840039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mSpinners.isShown();
841039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
842039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
843039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
844039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onConfigurationChanged(Configuration newConfig) {
845039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(newConfig.locale);
846039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
847039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
848039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
849039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public Parcelable onSaveInstanceState(Parcelable superState) {
850039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
851039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
852039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
853039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
854039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onRestoreInstanceState(Parcelable state) {
855039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            SavedState ss = (SavedState) state;
856039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(ss.mYear, ss.mMonth, ss.mDay);
857039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
858039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
859039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
860039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
861039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
862039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
863039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            onPopulateAccessibilityEvent(event);
864e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov            return true;
865e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov        }
866e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
867039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
868039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
869039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
870039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String selectedDateUtterance = DateUtils.formatDateTime(mContext,
871039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mCurrentDate.getTimeInMillis(), flags);
872039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            event.getText().add(selectedDateUtterance);
873039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
874156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov
875039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
876039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
877039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            event.setClassName(DatePicker.class.getName());
878039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
879156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov
880039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
881039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
882039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            info.setClassName(DatePicker.class.getName());
883039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
884e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim
885039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
886039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Sets the current locale.
887039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
888039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param locale The current locale.
889039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
890039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
891039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
892039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            super.setCurrentLocale(locale);
893039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
894039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate = getCalendarForLocale(mTempDate, locale);
895039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMinDate = getCalendarForLocale(mMinDate, locale);
896039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMaxDate = getCalendarForLocale(mMaxDate, locale);
897039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
898039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
899039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
900039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mShortMonths = new DateFormatSymbols().getShortMonths();
901039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
902039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (usingNumericMonths()) {
903039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                // We're in a locale where a date should either be all-numeric, or all-text.
904039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                // All-text would require custom NumberPicker formatters for day and year.
905039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mShortMonths = new String[mNumberOfMonths];
906039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                for (int i = 0; i < mNumberOfMonths; ++i) {
907039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mShortMonths[i] = String.format("%d", i + 1);
908039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
909039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
910e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim        }
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
912039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
913039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Tests whether the current locale is one where there are no real month names,
914039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * such as Chinese, Japanese, or Korean locales.
915039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
916039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean usingNumericMonths() {
917039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
918039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
920039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
921039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Gets a calendar for locale bootstrapped with the value of a given calendar.
922039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
923039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param oldCalendar The old calendar.
924039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param locale The locale.
925039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
926039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
927039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (oldCalendar == null) {
928039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return Calendar.getInstance(locale);
929039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
930039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                final long currentTimeMillis = oldCalendar.getTimeInMillis();
931039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                Calendar newCalendar = Calendar.getInstance(locale);
932039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                newCalendar.setTimeInMillis(currentTimeMillis);
933039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return newCalendar;
934039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
935039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
937039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
938039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Reorders the spinners according to the date format that is
939039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * explicitly set by the user and if no such is set fall back
940039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * to the current locale's default format.
941039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
942039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void reorderSpinners() {
943039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners.removeAllViews();
944039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // We use numeric spinners for year and day, but textual months. Ask icu4c what
945039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // order the user's locale uses for that combination. http://b/7207103.
946f8abeb8457feb766fb45829f6b175a22d4814d66Elliott Hughes            String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
947039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            char[] order = ICU.getDateFormatOrder(pattern);
948039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int spinnerCount = order.length;
949039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            for (int i = 0; i < spinnerCount; i++) {
950039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                switch (order[i]) {
951039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'd':
952039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mDaySpinner);
953039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mDaySpinner, spinnerCount, i);
954039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
955039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'M':
956039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mMonthSpinner);
957039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mMonthSpinner, spinnerCount, i);
958039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
959039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'y':
960039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mYearSpinner);
961039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mYearSpinner, spinnerCount, i);
962039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
963039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    default:
964039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        throw new IllegalArgumentException(Arrays.toString(order));
965039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
966039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
967039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
970039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Parses the given <code>date</code> and in case of success sets the result
971039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * to the <code>outDate</code>.
972039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
973039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @return True if the date was parsed.
974039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
975039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean parseDate(String date, Calendar outDate) {
976039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            try {
977039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                outDate.setTime(mDateFormat.parse(date));
978039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return true;
979039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } catch (ParseException e) {
980039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
981039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return false;
982039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
983039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9842bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu
985039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean isNewDate(int year, int month, int dayOfMonth) {
986039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return (mCurrentDate.get(Calendar.YEAR) != year
987039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
988039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
9892bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        }
990e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson
991039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setDate(int year, int month, int dayOfMonth) {
992039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate.set(year, month, dayOfMonth);
993039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.before(mMinDate)) {
994039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
995039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else if (mCurrentDate.after(mMaxDate)) {
996039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
997039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
998039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
999039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1000039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateSpinners() {
1001039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the spinner ranges respecting the min and max dates
1002039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.equals(mMinDate)) {
1003039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1004039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
1005039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(false);
1006039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1007039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
1008039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
1009039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(false);
1010039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else if (mCurrentDate.equals(mMaxDate)) {
1011039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
1012039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1013039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(false);
1014039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1015039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
1016039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
1017039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(false);
1018039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
1019039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(1);
1020039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
1021039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(true);
1022039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1023039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(0);
1024039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(11);
1025039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(true);
1026039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1027039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1028039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // make sure the month names are a zero based array
1029039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // with the months in the month spinner
1030039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String[] displayedValues = Arrays.copyOfRange(mShortMonths,
1031039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
1032039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setDisplayedValues(displayedValues);
1033039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1034039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // year spinner range does not change based on the current date
1035039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
1036039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
1037039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setWrapSelectorWheel(false);
1038039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1039039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the spinner values
1040039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
1041039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
1042039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1043039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1044039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (usingNumericMonths()) {
1045039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
1046039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1047039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1048039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1049039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1050039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Updates the calendar view with the current date.
1051039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1052039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateCalendarView() {
1053039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
1054039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1055039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1056039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1057039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1058039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Notifies the listener, if such, for a change in the selected date.
1059039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1060039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void notifyDateChanged() {
1061039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
1062039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mOnDateChangedListener != null) {
1063039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
1064039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        getDayOfMonth());
1065039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1066039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1067039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1068039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1069039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Sets the IME options for a spinner based on its ordering.
1070039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
1071039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinner The spinner.
1072039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinnerCount The total spinner count.
1073039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinnerIndex The index of the given spinner.
1074039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1075039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
1076039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int imeOptions;
1077039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (spinnerIndex < spinnerCount - 1) {
1078039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                imeOptions = EditorInfo.IME_ACTION_NEXT;
1079039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
1080039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                imeOptions = EditorInfo.IME_ACTION_DONE;
1081039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1082039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
1083039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            input.setImeOptions(imeOptions);
1084039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1085039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1086039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setContentDescriptions() {
1087039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Day
1088039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mDaySpinner, R.id.increment,
1089039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_day_button);
1090039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mDaySpinner, R.id.decrement,
1091039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_day_button);
1092039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Month
1093039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mMonthSpinner, R.id.increment,
1094039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_month_button);
1095039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mMonthSpinner, R.id.decrement,
1096039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_month_button);
1097039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Year
1098039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mYearSpinner, R.id.increment,
1099039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_year_button);
1100039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mYearSpinner, R.id.decrement,
1101039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_year_button);
1102039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1103039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1104039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void trySetContentDescription(View root, int viewId, int contDescResId) {
1105039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            View target = root.findViewById(viewId);
1106039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (target != null) {
1107039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                target.setContentDescription(mContext.getString(contDescResId));
1108039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1109039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1110039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1111039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateInputState() {
1112039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Make sure that if the user changes the value and the IME is active
1113039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // for one of the inputs if this widget, the IME is closed. If the user
1114039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // changed the value via the IME and there is a next input the IME will
1115039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // be shown, otherwise the user chose another means of changing the
1116039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // value and having the IME up makes no sense.
1117039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
1118039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (inputMethodManager != null) {
1119039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (inputMethodManager.isActive(mYearSpinnerInput)) {
1120039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mYearSpinnerInput.clearFocus();
1121039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1122039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
1123039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mMonthSpinnerInput.clearFocus();
1124039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1125039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
1126039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mDaySpinnerInput.clearFocus();
1127039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1128039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
11296304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov            }
11306304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov        }
11316304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov    }
11326304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov
1133a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov    /**
113450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     * Class for managing state storing/restoring.
113550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
113650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    private static class SavedState extends BaseSavedState {
113750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
113850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mYear;
113950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
114050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mMonth;
114150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
114250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mDay;
114350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
114450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        /**
114550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         * Constructor called from {@link DatePicker#onSaveInstanceState()}
114650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         */
114750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private SavedState(Parcelable superState, int year, int month, int day) {
114850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super(superState);
114950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mYear = year;
115050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mMonth = month;
115150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mDay = day;
115250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        }
115350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
115450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        /**
115550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         * Constructor called from {@link #CREATOR}
115650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         */
115750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private SavedState(Parcel in) {
115850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super(in);
115950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mYear = in.readInt();
116050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mMonth = in.readInt();
116150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mDay = in.readInt();
1162e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson        }
116350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
116450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        @Override
116550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        public void writeToParcel(Parcel dest, int flags) {
116650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super.writeToParcel(dest, flags);
116750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mYear);
116850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mMonth);
116950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mDay);
117050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        }
117150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
117250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        @SuppressWarnings("all")
117350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        // suppress unused and hiding
117450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
117550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
117650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            public SavedState createFromParcel(Parcel in) {
117750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov                return new SavedState(in);
117850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            }
117950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
118050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            public SavedState[] newArray(int size) {
118150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov                return new SavedState[size];
118250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            }
118350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        };
1184e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson    }
11853fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov}
1186