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
198817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport android.annotation.IntDef;
20518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viveretteimport android.annotation.Nullable;
218817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport android.annotation.TestApi;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.Widget;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
24f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport android.content.res.Configuration;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
2668763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.Calendar;
2768763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.TimeZone;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
30dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanuimport android.text.format.DateUtils;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
329668903731c272e51ce610598c052ef411c9d89fPhilip P. Moltmannimport android.util.Log;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
34d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganovimport android.view.View;
35305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Lemeimport android.view.ViewStructure;
368a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
37640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillManager;
38640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillValue;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4099441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.R;
4199441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas
428817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport java.lang.annotation.Retention;
438817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport java.lang.annotation.RetentionPolicy;
44dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport java.util.Locale;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
47d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * Provides a widget for selecting a date.
48d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * <p>
49d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
50d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * set to {@code spinner}, the date can be selected using year, month, and day
51d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * spinners or a {@link CalendarView}. The set of spinners and the calendar
52d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * view are automatically synchronized. The client can customize whether only
53d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * the spinners, or only the calendar view, or both to be displayed.
54d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * </p>
55d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * <p>
56d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
57d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * set to {@code calendar}, the month and day can be selected using a
58d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * calendar-style view while the year can be selected separately using a list.
59d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * </p>
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
83d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * @attr ref android.R.styleable#DatePicker_datePickerMode
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout {
879668903731c272e51ce610598c052ef411c9d89fPhilip P. Moltmann    private static final String LOG_TAG = DatePicker.class.getSimpleName();
889668903731c272e51ce610598c052ef411c9d89fPhilip P. Moltmann
898817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /**
908817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * Presentation mode for the Holo-style date picker that uses a set of
918817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * {@link android.widget.NumberPicker}s.
928817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     *
938817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @see #getMode()
948817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @hide Visible for testing only.
958817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     */
968817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TestApi
978817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public static final int MODE_SPINNER = 1;
988817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
998817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /**
1008817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * Presentation mode for the Material-style date picker that uses a
1018817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * calendar.
1028817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     *
1038817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @see #getMode()
1048817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @hide Visible for testing only.
1058817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     */
1068817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TestApi
1078817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public static final int MODE_CALENDAR = 2;
1088817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
1098817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /** @hide */
110ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    @IntDef(prefix = { "MODE_" }, value = {
111ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            MODE_SPINNER,
112ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            MODE_CALENDAR
113ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    })
1148817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @Retention(RetentionPolicy.SOURCE)
1158817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public @interface DatePickerMode {}
1163053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase
11760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private final DatePickerDelegate mDelegate;
118bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1198817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @DatePickerMode
1208817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    private final int mMode;
1218817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * The callback used to indicate the user changed the date.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDateChangedListener {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
128e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         * Called upon a date change.
129e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         *
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param view The view associated with this listener.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param year The year that was set.
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param monthOfYear The month that was set (0-11) for compatibility
13350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         *            with {@link java.util.Calendar}.
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dayOfMonth The day of the month that was set.
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context, AttributeSet attrs) {
1444243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov        this(context, attrs, R.attr.datePickerStyle);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
147617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
148617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
149617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
150617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
151617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
152617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
154d04a697ede5a372f96f87b80cf99a74dd12dbac4Felipe Leme        // DatePicker is important by default, unless app developer overrode attribute.
155d04a697ede5a372f96f87b80cf99a74dd12dbac4Felipe Leme        if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) {
156d04a697ede5a372f96f87b80cf99a74dd12dbac4Felipe Leme            setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
157d04a697ede5a372f96f87b80cf99a74dd12dbac4Felipe Leme        }
158d04a697ede5a372f96f87b80cf99a74dd12dbac4Felipe Leme
15960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
16060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                defStyleAttr, defStyleRes);
1618817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        final boolean isDialogMode = a.getBoolean(R.styleable.DatePicker_dialogMode, false);
1628817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        final int requestedMode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
1630a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
164bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        a.recycle();
165bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1668817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        if (requestedMode == MODE_CALENDAR && isDialogMode) {
1678817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            // You want MODE_CALENDAR? YOU CAN'T HANDLE MODE_CALENDAR! Well,
1688817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            // maybe you can depending on your screen size. Let's check...
1698817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            mMode = context.getResources().getInteger(R.integer.date_picker_mode);
1708817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        } else {
1718817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            mMode = requestedMode;
1728817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        }
1738817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
1748817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        switch (mMode) {
1753053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_CALENDAR:
1763053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1773053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
1783053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_SPINNER:
1793053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            default:
1803053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1813053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
182bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
1830a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
1840a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek != 0) {
1850a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            setFirstDayOfWeek(firstDayOfWeek);
1860a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
187305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
188305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        mDelegate.setAutoFillChangeListener((v, y, m, d) -> {
189640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme            final AutofillManager afm = context.getSystemService(AutofillManager.class);
190305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme            if (afm != null) {
1912f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov                afm.notifyValueChanged(this);
192305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme            }
193305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        });
194bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
195bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1963053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
197bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1983053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerSpinnerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
199bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
200bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
2013053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs,
202bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
2033053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr,
204bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                defStyleRes);
205bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
206bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
207bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
2088817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @return the picker's presentation mode, one of {@link #MODE_CALENDAR} or
2098817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     *         {@link #MODE_SPINNER}
2108817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @attr ref android.R.styleable#DatePicker_datePickerMode
2118817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @hide Visible for testing only.
2128817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     */
2138817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @DatePickerMode
2148817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TestApi
2158817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public int getMode() {
2168817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        return mMode;
2178817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    }
2188817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
2198817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /**
220039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * Initialize the state. If the provided values designate an inconsistent
221039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * date the values are normalized before updating the spinners.
222039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
223039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The initial year.
224039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param monthOfYear The initial month <strong>starting from zero</strong>.
225039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The initial day of the month.
226039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param onDateChangedListener How user is notified date is changed by
227039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *            user, can be null.
228039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
229039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
230039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                     OnDateChangedListener onDateChangedListener) {
231039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
232039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
23313427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov
234039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
23568640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri     * Set the callback that indicates the date has been adjusted by the user.
23668640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri     *
23768640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri     * @param onDateChangedListener How user is notified date is changed by
23868640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri     *            user, can be null.
23968640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri     */
24068640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri    public void setOnDateChangedListener(OnDateChangedListener onDateChangedListener) {
24168640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri        mDelegate.setOnDateChangedListener(onDateChangedListener);
24268640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri    }
24368640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri
24468640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri    /**
245bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Update the current date.
246039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
247039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The year.
248039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param month The month which is <strong>starting from zero</strong>.
249039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The day of the month.
250039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
251039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
252039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.updateDate(year, month, dayOfMonth);
253039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
254e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
255039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
256039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected year.
257039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
258039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getYear() {
259039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getYear();
260039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
2613fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
262039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
263039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected month.
264039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
265039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getMonth() {
266039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getMonth();
267039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
2684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
269039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
270039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected day of month.
271039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
272039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getDayOfMonth() {
273039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getDayOfMonth();
274e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
275e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
276e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
277e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the minimal date supported by this {@link DatePicker} in
278e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
279e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
280e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
281e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default minimal date is 01/01/1900.
282e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
283e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
284e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The minimal supported date.
285e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
286e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMinDate() {
287bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMinDate().getTimeInMillis();
288e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
289e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
290e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
291e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the minimal date supported by this {@link NumberPicker} in
292e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
293e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
294e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
295e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param minDate The minimal supported date.
296e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
297e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMinDate(long minDate) {
298039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMinDate(minDate);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
30128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    /**
302e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the maximal date supported by this {@link DatePicker} in
303e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
304e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
305e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
306e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default maximal date is 12/31/2100.
30728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     * <p>
30828104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     *
309e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The maximal supported date.
310e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
311e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMaxDate() {
312bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMaxDate().getTimeInMillis();
313e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
314e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
315e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
316e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the maximal date supported by this {@link DatePicker} in
317e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
318e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
319e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
320e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param maxDate The maximal supported date.
32128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     */
322e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMaxDate(long maxDate) {
323039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMaxDate(maxDate);
32428104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    }
32528104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov
326518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    /**
327518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * Sets the callback that indicates the current date is valid.
328518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     *
329518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @param callback the callback, may be null
330518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @hide
331518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     */
332518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public void setValidationCallback(@Nullable ValidationCallback callback) {
333518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        mDelegate.setValidationCallback(callback);
334518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    }
335518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setEnabled(boolean enabled) {
338039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        if (mDelegate.isEnabled() == enabled) {
33951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov            return;
34051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov        }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setEnabled(enabled);
342039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setEnabled(enabled);
34351c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    }
34451c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov
34551c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    @Override
34651c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    public boolean isEnabled() {
347039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.isEnabled();
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
350a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
3518a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    @Override
352a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
353039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.dispatchPopulateAccessibilityEvent(event);
3543fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    }
3553fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
356a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
3573fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    @Override
358a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
359a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        super.onPopulateAccessibilityEventInternal(event);
360039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onPopulateAccessibilityEvent(event);
3618a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    }
3628a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov
3638a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
364a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn    public CharSequence getAccessibilityClassName() {
365a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn        return DatePicker.class.getName();
3668a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3678a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
3688a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
369f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    protected void onConfigurationChanged(Configuration newConfig) {
370f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        super.onConfigurationChanged(newConfig);
371039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onConfigurationChanged(newConfig);
372f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    }
373f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
37450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
3750a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Sets the first day of week.
3760a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3770a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @param firstDayOfWeek The first day of the week conforming to the
3780a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *            {@link CalendarView} APIs.
3790a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3800a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3810a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3820a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3830a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3840a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3850a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3860a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3870a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3880a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3890a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
3900a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) {
3910a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7");
3920a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
3930a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
3940a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3950a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3960a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
3970a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Gets the first day of week.
3980a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3990a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @return The first day of the week conforming to the {@link CalendarView}
4000a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *         APIs.
4010a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
4020a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
4030a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
4040a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
4050a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
4060a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
4070a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
4080a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
4090a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
4100a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
4110a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public int getFirstDayOfWeek() {
4120a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        return mDelegate.getFirstDayOfWeek();
4130a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4140a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4150a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
416452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Returns whether the {@link CalendarView} is shown.
417452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <p>
418452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <strong>Note:</strong> This method returns {@code false} when the
419452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
420452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * to {@code calendar}.
421e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
422452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @return {@code true} if the calendar view is shown
4235f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarView()
4240e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * @deprecated Not supported by Material-style {@code calendar} mode
425e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
4260e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette    @Deprecated
427e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getCalendarViewShown() {
428039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarViewShown();
429e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
430e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
431e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
432452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Returns the {@link CalendarView} used by this picker.
433d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * <p>
4340e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * <strong>Note:</strong> This method throws an
4350e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * {@link UnsupportedOperationException} when the
436d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
437d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * to {@code calendar}.
4385f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     *
439452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @return the calendar view
4405f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarViewShown()
4410e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * @deprecated Not supported by Material-style {@code calendar} mode
4420e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * @throws UnsupportedOperationException if called when the picker is
4430e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     *         displayed in {@code calendar} mode
4445f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     */
4450e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette    @Deprecated
4460a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public CalendarView getCalendarView() {
447039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarView();
4485f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    }
4495f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov
4505f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    /**
451e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the {@link CalendarView} is shown.
452d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * <p>
453452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <strong>Note:</strong> Calling this method has no effect when the
454d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
455d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * to {@code calendar}.
456e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
457452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @param shown {@code true} to show the calendar view, {@code false} to
458452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     *              hide it
4590e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * @deprecated Not supported by Material-style {@code calendar} mode
460e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
4610e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette    @Deprecated
462e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setCalendarViewShown(boolean shown) {
463039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setCalendarViewShown(shown);
464e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
465e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
466e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
467452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Returns whether the spinners are shown.
468452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <p>
469835d7986061bbec2cd3433058f67d2efffe1bdeeAlan Viverette     * <strong>Note:</strong> his method returns {@code false} when the
470452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
471452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * to {@code calendar}.
472e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
473452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @return {@code true} if the spinners are shown
4740e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * @deprecated Not supported by Material-style {@code calendar} mode
47550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
4760e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette    @Deprecated
477e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getSpinnersShown() {
478039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getSpinnersShown();
479e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
480e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
481e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
482e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the spinners are shown.
483452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <p>
484452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Calling this method has no effect when the
485452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
486452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * to {@code calendar}.
487e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
488452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @param shown {@code true} to show the spinners, {@code false} to hide
489452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     *              them
4900e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette     * @deprecated Not supported by Material-style {@code calendar} mode
491e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
4920e672148a7c7292efdff0f641177ab06cd9d4968Alan Viverette    @Deprecated
493e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setSpinnersShown(boolean shown) {
494039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setSpinnersShown(shown);
495039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
496039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
497039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
498039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
499d015e3454ec1271ba6e5e3e6f0e5f7459b8b09eaAlan Viverette        dispatchThawSelfOnly(container);
500039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
501039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
502039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
503039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected Parcelable onSaveInstanceState() {
504039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable superState = super.onSaveInstanceState();
505039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.onSaveInstanceState(superState);
506039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
507039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
508039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
509039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void onRestoreInstanceState(Parcelable state) {
510a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        BaseSavedState ss = (BaseSavedState) state;
511039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        super.onRestoreInstanceState(ss.getSuperState());
512039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onRestoreInstanceState(ss);
513e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
514e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
515e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
516039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate interface that defined the public API of the DatePicker. Allows different
517039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * DatePicker implementations. This would need to be implemented by the DatePicker delegates
518039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * for the real behavior.
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
521f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
522039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    interface DatePickerDelegate {
523039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void init(int year, int monthOfYear, int dayOfMonth,
524039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                  OnDateChangedListener onDateChangedListener);
525f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
52668640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri        void setOnDateChangedListener(OnDateChangedListener onDateChangedListener);
527305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        void setAutoFillChangeListener(OnDateChangedListener onDateChangedListener);
52868640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri
529039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void updateDate(int year, int month, int dayOfMonth);
530f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
531039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getYear();
532039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getMonth();
533039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getDayOfMonth();
534f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme
535f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        void autofill(AutofillValue value);
536f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        AutofillValue getAutofillValue();
537f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
5380a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        void setFirstDayOfWeek(int firstDayOfWeek);
5390a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        int getFirstDayOfWeek();
5400a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
541039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMinDate(long minDate);
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMinDate();
543949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
544039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMaxDate(long maxDate);
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMaxDate();
546f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
547039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setEnabled(boolean enabled);
548039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean isEnabled();
549039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        CalendarView getCalendarView();
551039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
552039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setCalendarViewShown(boolean shown);
553039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getCalendarViewShown();
554039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
555039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setSpinnersShown(boolean shown);
556039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getSpinnersShown();
557039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
558518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void setValidationCallback(ValidationCallback callback);
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
560039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onConfigurationChanged(Configuration newConfig);
561039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
562039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable onSaveInstanceState(Parcelable superState);
563039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onRestoreInstanceState(Parcelable state);
564039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
565039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
566039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onPopulateAccessibilityEvent(AccessibilityEvent event);
567949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    }
568949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
569949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    /**
570039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * An abstract class which can be used as a start for DatePicker implementations
571f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    abstract static class AbstractDatePickerDelegate implements DatePickerDelegate {
573039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The delegator
574039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected DatePicker mDelegator;
575039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
576039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The context
577039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Context mContext;
578039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
579f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        // NOTE: when subclasses change this variable, they must call resetAutofilledValue().
580dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu        protected Calendar mCurrentDate;
581dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu
582039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The current locale
583039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Locale mCurrentLocale;
584039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
585039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // Callbacks
586518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected OnDateChangedListener mOnDateChangedListener;
587305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        protected OnDateChangedListener mAutoFillChangeListener;
588518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected ValidationCallback mValidationCallback;
589039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
590f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        // The value that was passed to autofill() - it must be stored because it getAutofillValue()
591f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        // must return the exact same value that was autofilled, otherwise the widget will not be
592f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        // properly highlighted after autofill().
593f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        private long mAutofilledValue;
594f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme
595bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
596039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
597039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
598039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
599039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
600f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        }
601f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
602039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
6030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            if (!locale.equals(mCurrentLocale)) {
6040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                mCurrentLocale = locale;
6050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                onLocaleChanged(locale);
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
608518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
609518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        @Override
61068640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri        public void setOnDateChangedListener(OnDateChangedListener callback) {
61168640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri            mOnDateChangedListener = callback;
61268640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri        }
61368640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri
61468640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri        @Override
615305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        public void setAutoFillChangeListener(OnDateChangedListener callback) {
616305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme            mAutoFillChangeListener = callback;
617305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        }
618305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
619305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        @Override
620518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        public void setValidationCallback(ValidationCallback callback) {
621518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            mValidationCallback = callback;
622518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
623518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
624305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        @Override
625f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        public final void autofill(AutofillValue value) {
626f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            if (value == null || !value.isDate()) {
627f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme                Log.w(LOG_TAG, value + " could not be autofilled into " + this);
628f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme                return;
629f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            }
630f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme
631f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            final long time = value.getDateValue();
632f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme
633f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            final Calendar cal = Calendar.getInstance(mCurrentLocale);
634f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            cal.setTimeInMillis(time);
635305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme            updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
636305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme                    cal.get(Calendar.DAY_OF_MONTH));
637f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme
638f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            // Must set mAutofilledValue *after* calling subclass method to make sure the value
639f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            // returned by getAutofillValue() matches it.
640f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            mAutofilledValue = time;
641305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        }
642305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
643305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        @Override
644f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        public final AutofillValue getAutofillValue() {
645f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            final long time = mAutofilledValue != 0
646f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme                    ? mAutofilledValue
647f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme                    : mCurrentDate.getTimeInMillis();
648f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            return AutofillValue.forDate(time);
649f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        }
650f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme
651f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        /**
652f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme         * This method must be called every time the value of the year, month, and/or day is
653f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme         * changed by a subclass method.
654f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme         */
655f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        protected void resetAutofilledValue() {
656f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme            mAutofilledValue = 0;
657305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        }
658305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
659518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected void onValidationChanged(boolean valid) {
660518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            if (mValidationCallback != null) {
661518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette                mValidationCallback.onValidationChanged(valid);
662518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            }
663518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
6640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
6650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        protected void onLocaleChanged(Locale locale) {
6660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // Stub.
6670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
668039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
669dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu        @Override
670dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu        public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
671dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu            event.getText().add(getFormattedCurrentDate());
672dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu        }
673dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu
674dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu        protected String getFormattedCurrentDate() {
675dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu           return DateUtils.formatDateTime(mContext, mCurrentDate.getTimeInMillis(),
676dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu                   DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR
677dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu                           | DateUtils.FORMAT_SHOW_WEEKDAY);
678dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu        }
679dd80f0065c0088bff30f9ce5e166df47ddf10690Andrei Stingaceanu
6806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        /**
6816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette         * Class for managing state storing/restoring.
6826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette         */
6836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        static class SavedState extends View.BaseSavedState {
6846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mSelectedYear;
6856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mSelectedMonth;
6866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mSelectedDay;
6876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final long mMinDate;
6886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final long mMaxDate;
6896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mCurrentView;
6906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mListPosition;
6916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mListPositionOffset;
6926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
6936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public SavedState(Parcelable superState, int year, int month, int day, long minDate,
6946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    long maxDate) {
6956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                this(superState, year, month, day, minDate, maxDate, 0, 0, 0);
696039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
697039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
6986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            /**
6996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette             * Constructor called from {@link DatePicker#onSaveInstanceState()}
7006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette             */
7016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public SavedState(Parcelable superState, int year, int month, int day, long minDate,
7026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    long maxDate, int currentView, int listPosition, int listPositionOffset) {
7036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                super(superState);
7046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mSelectedYear = year;
7056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mSelectedMonth = month;
7066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mSelectedDay = day;
7076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMinDate = minDate;
7086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMaxDate = maxDate;
7096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mCurrentView = currentView;
7106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mListPosition = listPosition;
7116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mListPositionOffset = listPositionOffset;
712039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
713039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            /**
7156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette             * Constructor called from {@link #CREATOR}
7166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette             */
7176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private SavedState(Parcel in) {
7186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                super(in);
7196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mSelectedYear = in.readInt();
7206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mSelectedMonth = in.readInt();
7216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mSelectedDay = in.readInt();
7226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMinDate = in.readLong();
7236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMaxDate = in.readLong();
7246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mCurrentView = in.readInt();
7256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mListPosition = in.readInt();
7266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mListPositionOffset = in.readInt();
727039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
728039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            @Override
7306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public void writeToParcel(Parcel dest, int flags) {
7316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                super.writeToParcel(dest, flags);
7326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mSelectedYear);
7336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mSelectedMonth);
7346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mSelectedDay);
7356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeLong(mMinDate);
7366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeLong(mMaxDate);
7376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mCurrentView);
7386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mListPosition);
7396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mListPositionOffset);
740039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getSelectedDay() {
7436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mSelectedDay;
744039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getSelectedMonth() {
7476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mSelectedMonth;
748039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
749039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getSelectedYear() {
7516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mSelectedYear;
752039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
753039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public long getMinDate() {
7556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mMinDate;
756039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public long getMaxDate() {
7596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mMaxDate;
760039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getCurrentView() {
7636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mCurrentView;
764039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
765e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson
7666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getListPosition() {
7676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mListPosition;
768039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
769039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getListPositionOffset() {
7716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mListPositionOffset;
772039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
773039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            @SuppressWarnings("all")
7756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            // suppress unused and hiding
7766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
777039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                public SavedState createFromParcel(Parcel in) {
7796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    return new SavedState(in);
7806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                }
781039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
7826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                public SavedState[] newArray(int size) {
7836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    return new SavedState[size];
784039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
7856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            };
7866304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov        }
7876304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov    }
7886304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov
789a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov    /**
7906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * A callback interface for updating input validity when the date picker
7916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * when included into a dialog.
7926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     *
7936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @hide
79450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
7956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public interface ValidationCallback {
7966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        void onValidationChanged(boolean valid);
797e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson    }
798305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
799305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    @Override
800640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme    public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
801640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme        // This view is self-sufficient for autofill, so it needs to call
802305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        // onProvideAutoFillStructure() to fill itself, but it does not need to call
803305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        // dispatchProvideAutoFillStructure() to fill its children.
804e4f30650ac2b4e7b1b2a8962a3618506aec1b81aFelipe Leme        structure.setAutofillId(getAutofillId());
805640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme        onProvideAutofillStructure(structure, flags);
806305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    }
807305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
808305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    @Override
809955e252a95785192902da7c9f5610f8e40f97803Felipe Leme    public void autofill(AutofillValue value) {
810955e252a95785192902da7c9f5610f8e40f97803Felipe Leme        if (!isEnabled()) return;
811305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
812f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        mDelegate.autofill(value);
813305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    }
814305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
815305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    @Override
8168931e303700a5adb6e013c2b5a6cec621eede968Felipe Leme    public @AutofillType int getAutofillType() {
8178931e303700a5adb6e013c2b5a6cec621eede968Felipe Leme        return isEnabled() ? AUTOFILL_TYPE_DATE : AUTOFILL_TYPE_NONE;
818305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    }
819305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme
820305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    @Override
821640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme    public AutofillValue getAutofillValue() {
822f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        return isEnabled() ? mDelegate.getAutofillValue() : null;
823305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme    }
8243fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov}
825