DatePicker.java revision a54956a0bc611b1e9b3914edc7a604b59688f6b7
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/**
54d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * Provides a widget for selecting a date.
55d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * <p>
56d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
57d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * set to {@code spinner}, the date can be selected using year, month, and day
58d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * spinners or a {@link CalendarView}. The set of spinners and the calendar
59d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * view are automatically synchronized. The client can customize whether only
60d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * the spinners, or only the calendar view, or both to be displayed.
61d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * </p>
62d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * <p>
63d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
64d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * set to {@code calendar}, the month and day can be selected using a
65d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * calendar-style view while the year can be selected separately using a list.
66d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * </p>
6750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * <p>
684c359b76f9a030f92a302ba74a528faa170bad4eScott Main * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
694c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide.
7050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * </p>
71e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p>
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}.
73e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * </p>
74e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov *
75e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_startYear
76e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_endYear
77e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_maxDate
78e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_minDate
79e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_spinnersShown
80e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_calendarViewShown
81ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette * @attr ref android.R.styleable#DatePicker_dayOfWeekBackground
8260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_dayOfWeekTextAppearance
83ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette * @attr ref android.R.styleable#DatePicker_headerBackground
8460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerMonthTextAppearance
8560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerDayOfMonthTextAppearance
8660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerYearTextAppearance
8760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_yearListItemTextAppearance
8860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_yearListSelectorColor
89bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * @attr ref android.R.styleable#DatePicker_calendarTextColor
90d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * @attr ref android.R.styleable#DatePicker_datePickerMode
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout {
94e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    private static final String LOG_TAG = DatePicker.class.getSimpleName();
95e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
963053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static final int MODE_SPINNER = 1;
973053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static final int MODE_CALENDAR = 2;
983053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase
9960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private final DatePickerDelegate mDelegate;
100bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
102e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * The callback used to indicate the user changes\d the date.
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDateChangedListener {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
107e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         * Called upon a date change.
108e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         *
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param view The view associated with this listener.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param year The year that was set.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param monthOfYear The month that was set (0-11) for compatibility
11250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         *            with {@link java.util.Calendar}.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dayOfMonth The day of the month that was set.
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context, AttributeSet attrs) {
1234243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov        this(context, attrs, R.attr.datePickerStyle);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
126617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
127617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
128617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
129617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
130617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
131617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
13460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                defStyleAttr, defStyleRes);
135518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        final int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
1360a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
137bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        a.recycle();
138bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1393053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        switch (mode) {
1403053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_CALENDAR:
1413053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1423053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
1433053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_SPINNER:
1443053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            default:
1453053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1463053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
147bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
1480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
1490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek != 0) {
1500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            setFirstDayOfWeek(firstDayOfWeek);
1510a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
152bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
153bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1543053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
155bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1563053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerSpinnerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
157bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
158bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1593053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs,
160bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1613053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr,
162bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                defStyleRes);
163bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
164bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
165bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
166039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * Initialize the state. If the provided values designate an inconsistent
167039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * date the values are normalized before updating the spinners.
168039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
169039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The initial year.
170039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param monthOfYear The initial month <strong>starting from zero</strong>.
171039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The initial day of the month.
172039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param onDateChangedListener How user is notified date is changed by
173039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *            user, can be null.
174039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
175039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
176039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                     OnDateChangedListener onDateChangedListener) {
177039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
178039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
17913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov
180039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
181bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Update the current date.
182039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
183039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The year.
184039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param month The month which is <strong>starting from zero</strong>.
185039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The day of the month.
186039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
187039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
188039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.updateDate(year, month, dayOfMonth);
189039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
190e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
191039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
192039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected year.
193039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
194039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getYear() {
195039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getYear();
196039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
1973fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
198039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
199039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected month.
200039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
201039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getMonth() {
202039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getMonth();
203039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
2044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
205039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
206039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected day of month.
207039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
208039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getDayOfMonth() {
209039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getDayOfMonth();
210e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
211e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
212e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
213e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the minimal date supported by this {@link DatePicker} in
214e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
215e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
216e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
217e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default minimal date is 01/01/1900.
218e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
219e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
220e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The minimal supported date.
221e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
222e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMinDate() {
223bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMinDate().getTimeInMillis();
224e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
225e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
226e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
227e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the minimal date supported by this {@link NumberPicker} in
228e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
229e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
230e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
231e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param minDate The minimal supported date.
232e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
233e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMinDate(long minDate) {
234039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMinDate(minDate);
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
23728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    /**
238e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the maximal date supported by this {@link DatePicker} in
239e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
240e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
241e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
242e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default maximal date is 12/31/2100.
24328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     * <p>
24428104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     *
245e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The maximal supported date.
246e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
247e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMaxDate() {
248bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMaxDate().getTimeInMillis();
249e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
250e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
251e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
252e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the maximal date supported by this {@link DatePicker} in
253e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
254e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
255e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
256e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param maxDate The maximal supported date.
25728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     */
258e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMaxDate(long maxDate) {
259039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMaxDate(maxDate);
26028104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    }
26128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov
262518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    /**
263518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * Sets the callback that indicates the current date is valid.
264518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     *
265518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @param callback the callback, may be null
266518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @hide
267518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     */
268518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public void setValidationCallback(@Nullable ValidationCallback callback) {
269518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        mDelegate.setValidationCallback(callback);
270518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    }
271518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setEnabled(boolean enabled) {
274039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        if (mDelegate.isEnabled() == enabled) {
27551c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov            return;
27651c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov        }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setEnabled(enabled);
278039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setEnabled(enabled);
27951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    }
28051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov
28151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    @Override
28251c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    public boolean isEnabled() {
283039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.isEnabled();
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
286a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
2878a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    @Override
288a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
289039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.dispatchPopulateAccessibilityEvent(event);
2903fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    }
2913fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
292a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
2933fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    @Override
294a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
295a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        super.onPopulateAccessibilityEventInternal(event);
296039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onPopulateAccessibilityEvent(event);
2978a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    }
2988a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov
299a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
300f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    @Override
301a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
302a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        super.onInitializeAccessibilityEventInternal(event);
303039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onInitializeAccessibilityEvent(event);
3048a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3058a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
306a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
3078a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
308a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
309a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        super.onInitializeAccessibilityNodeInfoInternal(info);
310039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onInitializeAccessibilityNodeInfo(info);
3118a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3128a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
3138a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
314f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    protected void onConfigurationChanged(Configuration newConfig) {
315f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        super.onConfigurationChanged(newConfig);
316039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onConfigurationChanged(newConfig);
317f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    }
318f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
31950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
3200a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Sets the first day of week.
3210a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3220a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @param firstDayOfWeek The first day of the week conforming to the
3230a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *            {@link CalendarView} APIs.
3240a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3250a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3260a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3270a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3280a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3290a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3300a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3310a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3320a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3330a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3340a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
3350a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) {
3360a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7");
3370a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
3380a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
3390a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3400a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3410a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
3420a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Gets the first day of week.
3430a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3440a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @return The first day of the week conforming to the {@link CalendarView}
3450a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *         APIs.
3460a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3470a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3510a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3520a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3530a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3540a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3550a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3560a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public int getFirstDayOfWeek() {
3570a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        return mDelegate.getFirstDayOfWeek();
3580a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3590a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3600a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
361e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets whether the {@link CalendarView} is shown.
362e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
363e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return True if the calendar view is shown.
3645f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarView()
365e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
366e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getCalendarViewShown() {
367039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarViewShown();
368e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
369e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
370e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
3715f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * Gets the {@link CalendarView}.
372d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * <p>
373d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * This method returns {@code null} when the
374d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
375d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * to {@code calendar}.
3765f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     *
3775f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @return The calendar view.
3785f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarViewShown()
3795f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     */
3800a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public CalendarView getCalendarView() {
381039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarView();
3825f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    }
3835f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov
3845f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    /**
385e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the {@link CalendarView} is shown.
386d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * <p>
387d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * Calling this method has no effect when the
388d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
389d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * to {@code calendar}.
390e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
391e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param shown True if the calendar view is to be shown.
392e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
393e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setCalendarViewShown(boolean shown) {
394039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setCalendarViewShown(shown);
395e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
396e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
397e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
398e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets whether the spinners are shown.
399e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
400e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return True if the spinners are shown.
40150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
402e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getSpinnersShown() {
403039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getSpinnersShown();
404e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
405e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
406e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
407e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the spinners are shown.
408e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
409e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param shown True if the spinners are to be shown.
410e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
411e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setSpinnersShown(boolean shown) {
412039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setSpinnersShown(shown);
413039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
414039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
415039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
416039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
417d015e3454ec1271ba6e5e3e6f0e5f7459b8b09eaAlan Viverette        dispatchThawSelfOnly(container);
418039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
419039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
420039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
421039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected Parcelable onSaveInstanceState() {
422039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable superState = super.onSaveInstanceState();
423039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.onSaveInstanceState(superState);
424039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
425039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
426039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
427039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void onRestoreInstanceState(Parcelable state) {
428a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        BaseSavedState ss = (BaseSavedState) state;
429039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        super.onRestoreInstanceState(ss.getSuperState());
430039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onRestoreInstanceState(ss);
431e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
432e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
433e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
434039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate interface that defined the public API of the DatePicker. Allows different
435039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * DatePicker implementations. This would need to be implemented by the DatePicker delegates
436039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * for the real behavior.
437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
439f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
440039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    interface DatePickerDelegate {
441039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void init(int year, int monthOfYear, int dayOfMonth,
442039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                  OnDateChangedListener onDateChangedListener);
443f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
444039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void updateDate(int year, int month, int dayOfMonth);
445f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
446039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getYear();
447039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getMonth();
448039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getDayOfMonth();
449f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
4500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        void setFirstDayOfWeek(int firstDayOfWeek);
4510a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        int getFirstDayOfWeek();
4520a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
453039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMinDate(long minDate);
454bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMinDate();
455949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
456039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMaxDate(long maxDate);
457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMaxDate();
458f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
459039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setEnabled(boolean enabled);
460039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean isEnabled();
461039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
462bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        CalendarView getCalendarView();
463039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
464039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setCalendarViewShown(boolean shown);
465039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getCalendarViewShown();
466039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
467039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setSpinnersShown(boolean shown);
468039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getSpinnersShown();
469039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
470518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void setValidationCallback(ValidationCallback callback);
471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
472039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onConfigurationChanged(Configuration newConfig);
473039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
474039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable onSaveInstanceState(Parcelable superState);
475039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onRestoreInstanceState(Parcelable state);
476039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
477039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
478039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onPopulateAccessibilityEvent(AccessibilityEvent event);
479039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onInitializeAccessibilityEvent(AccessibilityEvent event);
480039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
481949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    }
482949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
483949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    /**
484039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * An abstract class which can be used as a start for DatePicker implementations
485f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    abstract static class AbstractDatePickerDelegate implements DatePickerDelegate {
487039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The delegator
488039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected DatePicker mDelegator;
489039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
490039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The context
491039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Context mContext;
492039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
493039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The current locale
494039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Locale mCurrentLocale;
495039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
496039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // Callbacks
497518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected OnDateChangedListener mOnDateChangedListener;
498518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected ValidationCallback mValidationCallback;
499039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
501039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
502039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
503039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
504039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialization based on locale
505039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
506f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        }
507f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
508039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
509039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (locale.equals(mCurrentLocale)) {
510039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
512039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentLocale = locale;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
514518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
515518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        @Override
516518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        public void setValidationCallback(ValidationCallback callback) {
517518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            mValidationCallback = callback;
518518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
519518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
520518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected void onValidationChanged(boolean valid) {
521518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            if (mValidationCallback != null) {
522518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette                mValidationCallback.onValidationChanged(valid);
523518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            }
524518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
528518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * A callback interface for updating input validity when the date picker
529518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * when included into a dialog.
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
533518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public static interface ValidationCallback {
534518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void onValidationChanged(boolean valid);
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
538039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate implementing the basic DatePicker
53950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
5403053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate {
541039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
542039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final String DATE_FORMAT = "MM/dd/yyyy";
543039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
544039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final int DEFAULT_START_YEAR = 1900;
545039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
546039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final int DEFAULT_END_YEAR = 2100;
547039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
548039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
549039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
550039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_SPINNERS_SHOWN = true;
551039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
552039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_ENABLED_STATE = true;
553039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
554039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final LinearLayout mSpinners;
555039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
556039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mDaySpinner;
557039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
558039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mMonthSpinner;
559039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
560039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mYearSpinner;
561039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
562039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mDaySpinnerInput;
563039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
564039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mMonthSpinnerInput;
565039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
566039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mYearSpinnerInput;
567039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
568039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final CalendarView mCalendarView;
569039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
570039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private String[] mShortMonths;
571039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
572039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
573039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
574039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private int mNumberOfMonths;
575039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
576039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mTempDate;
577039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
578039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mMinDate;
579039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
580039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mMaxDate;
581039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
582039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mCurrentDate;
583039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
584039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
585039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
5863053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        DatePickerSpinnerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
587039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                int defStyleAttr, int defStyleRes) {
588039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            super(delegator, context);
589039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
590039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
591039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
592039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
593039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialization based on locale
594039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
595039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
596039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
597039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.styleable.DatePicker, defStyleAttr, defStyleRes);
598039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
599039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    DEFAULT_SPINNERS_SHOWN);
600039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            boolean calendarViewShown = attributesArray.getBoolean(
601039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
602039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
603039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    DEFAULT_START_YEAR);
604039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
605039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
606039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
607039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int layoutResourceId = attributesArray.getResourceId(
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    R.styleable.DatePicker_legacyLayout, R.layout.date_picker_legacy);
609039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            attributesArray.recycle();
610039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
611039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            LayoutInflater inflater = (LayoutInflater) context
612039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
613039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            inflater.inflate(layoutResourceId, mDelegator, true);
614039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
615039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            OnValueChangeListener onChangeListener = new OnValueChangeListener() {
616039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
617039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateInputState();
618039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
619039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    // take care of wrapping of days and months to update greater fields
620039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    if (picker == mDaySpinner) {
621039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
622039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        if (oldVal == maxDayOfMonth && newVal == 1) {
623039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, 1);
624039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else if (oldVal == 1 && newVal == maxDayOfMonth) {
625039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, -1);
626039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else {
627039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
628039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        }
629039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else if (picker == mMonthSpinner) {
630039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        if (oldVal == 11 && newVal == 0) {
631039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, 1);
632039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else if (oldVal == 0 && newVal == 11) {
633039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, -1);
634039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else {
635039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, newVal - oldVal);
636039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        }
637039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else if (picker == mYearSpinner) {
638039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mTempDate.set(Calendar.YEAR, newVal);
639039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else {
640039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        throw new IllegalArgumentException();
641039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    }
642039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    // now set the date to the adjusted one
643039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
644039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.get(Calendar.DAY_OF_MONTH));
645039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateSpinners();
646039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateCalendarView();
647039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    notifyDateChanged();
648039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
649039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            };
650039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
651039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners = (LinearLayout) mDelegator.findViewById(R.id.pickers);
652039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
653039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // calendar view day-picker
654039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView = (CalendarView) mDelegator.findViewById(R.id.calendar_view);
655039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
656039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
657039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    setDate(year, month, monthDay);
658039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateSpinners();
659039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    notifyDateChanged();
660039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
661039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            });
662039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
663039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // day
664039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner = (NumberPicker) mDelegator.findViewById(R.id.day);
665039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
666039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setOnLongPressUpdateInterval(100);
667039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setOnValueChangedListener(onChangeListener);
668039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
669039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
670039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // month
671039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner = (NumberPicker) mDelegator.findViewById(R.id.month);
672039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setMinValue(0);
673039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
674039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setDisplayedValues(mShortMonths);
675039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setOnLongPressUpdateInterval(200);
676039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setOnValueChangedListener(onChangeListener);
677039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
678039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
679039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // year
680039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner = (NumberPicker) mDelegator.findViewById(R.id.year);
681039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setOnLongPressUpdateInterval(100);
682039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setOnValueChangedListener(onChangeListener);
683039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
684039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
685039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // show only what the user required but make sure we
686039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // show something and the spinners have higher priority
687039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!spinnersShown && !calendarViewShown) {
688039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setSpinnersShown(true);
689039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
690039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setSpinnersShown(spinnersShown);
691039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setCalendarViewShown(calendarViewShown);
692039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
693039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
694039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the min date giving priority of the minDate over startYear
695039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.clear();
696039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!TextUtils.isEmpty(minDate)) {
697039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (!parseDate(minDate, mTempDate)) {
698039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.set(startYear, 0, 1);
699039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
700039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
701039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mTempDate.set(startYear, 0, 1);
702039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
703039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setMinDate(mTempDate.getTimeInMillis());
704039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
705039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the max date giving priority of the maxDate over endYear
706039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.clear();
707039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!TextUtils.isEmpty(maxDate)) {
708039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (!parseDate(maxDate, mTempDate)) {
709039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.set(endYear, 11, 31);
710039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
711039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
712039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mTempDate.set(endYear, 11, 31);
713039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
714039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setMaxDate(mTempDate.getTimeInMillis());
715039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
716039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialize to current date
717039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate.setTimeInMillis(System.currentTimeMillis());
718039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
719039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    .get(Calendar.DAY_OF_MONTH), null);
720039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
721039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // re-order the number spinners to match the current date format
722039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            reorderSpinners();
723039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
724039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // accessibility
725039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setContentDescriptions();
726039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
727039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // If not explicitly specified this view is important for accessibility.
728039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
729039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
730039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
731dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root        }
732dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root
733039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
734039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void init(int year, int monthOfYear, int dayOfMonth,
735039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                         OnDateChangedListener onDateChangedListener) {
736039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(year, monthOfYear, dayOfMonth);
737039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
738039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
739039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mOnDateChangedListener = onDateChangedListener;
740039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
742039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
743039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void updateDate(int year, int month, int dayOfMonth) {
744039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!isNewDate(year, month, dayOfMonth)) {
745039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
746039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
747039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(year, month, dayOfMonth);
748039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
749039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
750039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            notifyDateChanged();
751039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
753039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
754039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getYear() {
755039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.YEAR);
756039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
758039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
759039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getMonth() {
760039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.MONTH);
761039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
763039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
764039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getDayOfMonth() {
765039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.DAY_OF_MONTH);
766039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
767039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
768039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
7690a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        public void setFirstDayOfWeek(int firstDayOfWeek) {
7700a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            mCalendarView.setFirstDayOfWeek(firstDayOfWeek);
7710a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
7720a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
7730a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        @Override
7740a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        public int getFirstDayOfWeek() {
7750a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mCalendarView.getFirstDayOfWeek();
7760a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
7770a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
7780a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        @Override
779039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setMinDate(long minDate) {
780039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.setTimeInMillis(minDate);
781039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
782039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
783039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
784039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
785039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMinDate.setTimeInMillis(minDate);
786039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setMinDate(minDate);
787039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.before(mMinDate)) {
788039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
789039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                updateCalendarView();
790039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
791039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
792039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
793039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
794039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
795bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public Calendar getMinDate() {
796bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final Calendar minDate = Calendar.getInstance();
797bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            minDate.setTimeInMillis(mCalendarView.getMinDate());
798bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return minDate;
799039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
800039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
801039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
802039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setMaxDate(long maxDate) {
803039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.setTimeInMillis(maxDate);
804039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
805039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
806039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
807039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
808039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMaxDate.setTimeInMillis(maxDate);
809039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setMaxDate(maxDate);
810039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.after(mMaxDate)) {
811039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
812039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                updateCalendarView();
813039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
814039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
815039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
816039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
817039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
818bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public Calendar getMaxDate() {
819bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final Calendar maxDate = Calendar.getInstance();
820bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            maxDate.setTimeInMillis(mCalendarView.getMaxDate());
821bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return maxDate;
822039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
823039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
824039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
825039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setEnabled(boolean enabled) {
826039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setEnabled(enabled);
827039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setEnabled(enabled);
828039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setEnabled(enabled);
829039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setEnabled(enabled);
830039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mIsEnabled = enabled;
831039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
832039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
833039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
834039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean isEnabled() {
835039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mIsEnabled;
836039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
837039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
838039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
839039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public CalendarView getCalendarView() {
840039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCalendarView;
841039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
842039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
843039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
844039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setCalendarViewShown(boolean shown) {
845039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setVisibility(shown ? VISIBLE : GONE);
846039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
847039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
848039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
849039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean getCalendarViewShown() {
850039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return (mCalendarView.getVisibility() == View.VISIBLE);
851039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
852039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
853039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
854039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setSpinnersShown(boolean shown) {
855039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners.setVisibility(shown ? VISIBLE : GONE);
856039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
857039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
858039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
859039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean getSpinnersShown() {
860039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mSpinners.isShown();
861039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
862039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
863039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
864039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onConfigurationChanged(Configuration newConfig) {
865039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(newConfig.locale);
866039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
867039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
868039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
869039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public Parcelable onSaveInstanceState(Parcelable superState) {
870039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
871039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
872039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
873039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
874039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onRestoreInstanceState(Parcelable state) {
875039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            SavedState ss = (SavedState) state;
876039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(ss.mYear, ss.mMonth, ss.mDay);
877039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
878039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
879039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
880039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
881039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
882039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
883039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            onPopulateAccessibilityEvent(event);
884e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov            return true;
885e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov        }
886e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
887039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
888039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
889039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
890039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String selectedDateUtterance = DateUtils.formatDateTime(mContext,
891039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mCurrentDate.getTimeInMillis(), flags);
892039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            event.getText().add(selectedDateUtterance);
893039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
894156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov
895039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
896039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
897039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            event.setClassName(DatePicker.class.getName());
898039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
899156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov
900039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
901039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
902039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            info.setClassName(DatePicker.class.getName());
903039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
904e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim
905039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
906039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Sets the current locale.
907039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
908039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param locale The current locale.
909039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
910039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
911039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
912039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            super.setCurrentLocale(locale);
913039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
914039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate = getCalendarForLocale(mTempDate, locale);
915039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMinDate = getCalendarForLocale(mMinDate, locale);
916039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMaxDate = getCalendarForLocale(mMaxDate, locale);
917039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
918039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
919039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
920039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mShortMonths = new DateFormatSymbols().getShortMonths();
921039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
922039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (usingNumericMonths()) {
923039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                // We're in a locale where a date should either be all-numeric, or all-text.
924039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                // All-text would require custom NumberPicker formatters for day and year.
925039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mShortMonths = new String[mNumberOfMonths];
926039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                for (int i = 0; i < mNumberOfMonths; ++i) {
927039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mShortMonths[i] = String.format("%d", i + 1);
928039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
929039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
930e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim        }
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
932039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
933039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Tests whether the current locale is one where there are no real month names,
934039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * such as Chinese, Japanese, or Korean locales.
935039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
936039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean usingNumericMonths() {
937039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
938039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
940039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
941039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Gets a calendar for locale bootstrapped with the value of a given calendar.
942039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
943039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param oldCalendar The old calendar.
944039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param locale The locale.
945039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
946039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
947039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (oldCalendar == null) {
948039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return Calendar.getInstance(locale);
949039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
950039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                final long currentTimeMillis = oldCalendar.getTimeInMillis();
951039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                Calendar newCalendar = Calendar.getInstance(locale);
952039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                newCalendar.setTimeInMillis(currentTimeMillis);
953039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return newCalendar;
954039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
955039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
957039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
958039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Reorders the spinners according to the date format that is
959039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * explicitly set by the user and if no such is set fall back
960039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * to the current locale's default format.
961039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
962039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void reorderSpinners() {
963039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners.removeAllViews();
964039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // We use numeric spinners for year and day, but textual months. Ask icu4c what
965039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // order the user's locale uses for that combination. http://b/7207103.
966f8abeb8457feb766fb45829f6b175a22d4814d66Elliott Hughes            String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
967039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            char[] order = ICU.getDateFormatOrder(pattern);
968039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int spinnerCount = order.length;
969039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            for (int i = 0; i < spinnerCount; i++) {
970039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                switch (order[i]) {
971039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'd':
972039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mDaySpinner);
973039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mDaySpinner, spinnerCount, i);
974039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
975039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'M':
976039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mMonthSpinner);
977039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mMonthSpinner, spinnerCount, i);
978039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
979039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'y':
980039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mYearSpinner);
981039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mYearSpinner, spinnerCount, i);
982039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
983039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    default:
984039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        throw new IllegalArgumentException(Arrays.toString(order));
985039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
986039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
987039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
990039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Parses the given <code>date</code> and in case of success sets the result
991039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * to the <code>outDate</code>.
992039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
993039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @return True if the date was parsed.
994039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
995039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean parseDate(String date, Calendar outDate) {
996039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            try {
997039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                outDate.setTime(mDateFormat.parse(date));
998039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return true;
999039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } catch (ParseException e) {
1000039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
1001039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return false;
1002039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1003039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
10042bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu
1005039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean isNewDate(int year, int month, int dayOfMonth) {
1006039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return (mCurrentDate.get(Calendar.YEAR) != year
1007039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
1008039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
10092bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        }
1010e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson
1011039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setDate(int year, int month, int dayOfMonth) {
1012039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate.set(year, month, dayOfMonth);
1013039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.before(mMinDate)) {
1014039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
1015039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else if (mCurrentDate.after(mMaxDate)) {
1016039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
1017039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1018039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1019039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1020039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateSpinners() {
1021039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the spinner ranges respecting the min and max dates
1022039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.equals(mMinDate)) {
1023039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1024039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
1025039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(false);
1026039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1027039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
1028039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
1029039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(false);
1030039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else if (mCurrentDate.equals(mMaxDate)) {
1031039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
1032039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1033039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(false);
1034039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1035039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
1036039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
1037039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(false);
1038039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
1039039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(1);
1040039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
1041039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(true);
1042039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1043039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(0);
1044039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(11);
1045039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(true);
1046039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1047039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1048039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // make sure the month names are a zero based array
1049039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // with the months in the month spinner
1050039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String[] displayedValues = Arrays.copyOfRange(mShortMonths,
1051039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
1052039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setDisplayedValues(displayedValues);
1053039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1054039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // year spinner range does not change based on the current date
1055039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
1056039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
1057039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setWrapSelectorWheel(false);
1058039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1059039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the spinner values
1060039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
1061039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
1062039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1063039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1064039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (usingNumericMonths()) {
1065039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
1066039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1067039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1068039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1069039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1070039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Updates the calendar view with the current date.
1071039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1072039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateCalendarView() {
1073039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
1074039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1075039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1076039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1077039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1078039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Notifies the listener, if such, for a change in the selected date.
1079039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1080039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void notifyDateChanged() {
1081039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
1082039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mOnDateChangedListener != null) {
1083039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
1084039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        getDayOfMonth());
1085039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1086039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1087039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1088039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1089039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Sets the IME options for a spinner based on its ordering.
1090039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
1091039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinner The spinner.
1092039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinnerCount The total spinner count.
1093039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinnerIndex The index of the given spinner.
1094039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1095039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
1096039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int imeOptions;
1097039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (spinnerIndex < spinnerCount - 1) {
1098039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                imeOptions = EditorInfo.IME_ACTION_NEXT;
1099039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
1100039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                imeOptions = EditorInfo.IME_ACTION_DONE;
1101039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1102039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
1103039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            input.setImeOptions(imeOptions);
1104039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1105039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1106039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setContentDescriptions() {
1107039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Day
1108039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mDaySpinner, R.id.increment,
1109039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_day_button);
1110039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mDaySpinner, R.id.decrement,
1111039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_day_button);
1112039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Month
1113039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mMonthSpinner, R.id.increment,
1114039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_month_button);
1115039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mMonthSpinner, R.id.decrement,
1116039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_month_button);
1117039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Year
1118039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mYearSpinner, R.id.increment,
1119039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_year_button);
1120039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mYearSpinner, R.id.decrement,
1121039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_year_button);
1122039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1123039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1124039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void trySetContentDescription(View root, int viewId, int contDescResId) {
1125039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            View target = root.findViewById(viewId);
1126039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (target != null) {
1127039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                target.setContentDescription(mContext.getString(contDescResId));
1128039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1129039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1130039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1131039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateInputState() {
1132039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Make sure that if the user changes the value and the IME is active
1133039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // for one of the inputs if this widget, the IME is closed. If the user
1134039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // changed the value via the IME and there is a next input the IME will
1135039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // be shown, otherwise the user chose another means of changing the
1136039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // value and having the IME up makes no sense.
1137039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
1138039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (inputMethodManager != null) {
1139039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (inputMethodManager.isActive(mYearSpinnerInput)) {
1140039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mYearSpinnerInput.clearFocus();
1141039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1142039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
1143039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mMonthSpinnerInput.clearFocus();
1144039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1145039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
1146039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mDaySpinnerInput.clearFocus();
1147039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1148039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
11496304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov            }
11506304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov        }
11516304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov    }
11526304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov
1153a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov    /**
115450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     * Class for managing state storing/restoring.
115550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
115650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    private static class SavedState extends BaseSavedState {
115750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
115850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mYear;
115950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
116050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mMonth;
116150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
116250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mDay;
116350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
116450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        /**
116550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         * Constructor called from {@link DatePicker#onSaveInstanceState()}
116650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         */
116750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private SavedState(Parcelable superState, int year, int month, int day) {
116850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super(superState);
116950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mYear = year;
117050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mMonth = month;
117150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mDay = day;
117250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        }
117350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
117450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        /**
117550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         * Constructor called from {@link #CREATOR}
117650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         */
117750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private SavedState(Parcel in) {
117850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super(in);
117950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mYear = in.readInt();
118050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mMonth = in.readInt();
118150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mDay = in.readInt();
1182e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson        }
118350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
118450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        @Override
118550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        public void writeToParcel(Parcel dest, int flags) {
118650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super.writeToParcel(dest, flags);
118750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mYear);
118850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mMonth);
118950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mDay);
119050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        }
119150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
119250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        @SuppressWarnings("all")
119350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        // suppress unused and hiding
119450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
119550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
119650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            public SavedState createFromParcel(Parcel in) {
119750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov                return new SavedState(in);
119850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            }
119950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
120050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            public SavedState[] newArray(int size) {
120150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov                return new SavedState[size];
120250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            }
120350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        };
1204e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson    }
12053fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov}
1206