DatePicker.java revision 452fe349841476e4c7d17ab0652bdd4d45ce4595
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;
36a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganovimport android.view.inputmethod.EditorInfo;
376304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganovimport android.view.inputmethod.InputMethodManager;
38cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganovimport android.widget.NumberPicker.OnValueChangeListener;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport com.android.internal.R;
41f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
42949e9df25bccb736675f950591d3a286ae4052fcElliott Hughesimport java.text.DateFormatSymbols;
43e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.text.ParseException;
4403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischerimport java.text.SimpleDateFormat;
45156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganovimport java.util.Arrays;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar;
47dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport java.util.Locale;
48e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.util.TimeZone;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50659f145278ffd85f934a435dbec47ead685caf59Elliott Hughesimport libcore.icu.ICU;
51659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
53d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * Provides a widget for selecting a date.
54d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * <p>
55d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
56d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * set to {@code spinner}, the date can be selected using year, month, and day
57d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * spinners or a {@link CalendarView}. The set of spinners and the calendar
58d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * view are automatically synchronized. The client can customize whether only
59d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * the spinners, or only the calendar view, or both to be displayed.
60d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * </p>
61d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * <p>
62d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
63d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * set to {@code calendar}, the month and day can be selected using a
64d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * calendar-style view while the year can be selected separately using a list.
65d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * </p>
6650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * <p>
674c359b76f9a030f92a302ba74a528faa170bad4eScott Main * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
684c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide.
6950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * </p>
70e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p>
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}.
72e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * </p>
73e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov *
74e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_startYear
75e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_endYear
76e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_maxDate
77e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_minDate
78e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_spinnersShown
79e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_calendarViewShown
80ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette * @attr ref android.R.styleable#DatePicker_dayOfWeekBackground
8160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_dayOfWeekTextAppearance
82ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette * @attr ref android.R.styleable#DatePicker_headerBackground
8360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerMonthTextAppearance
8460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerDayOfMonthTextAppearance
8560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_headerYearTextAppearance
8660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_yearListItemTextAppearance
8760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette * @attr ref android.R.styleable#DatePicker_yearListSelectorColor
88bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * @attr ref android.R.styleable#DatePicker_calendarTextColor
89d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette * @attr ref android.R.styleable#DatePicker_datePickerMode
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout {
93e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    private static final String LOG_TAG = DatePicker.class.getSimpleName();
94e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
953053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static final int MODE_SPINNER = 1;
963053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static final int MODE_CALENDAR = 2;
973053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase
9860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private final DatePickerDelegate mDelegate;
99bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1010ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * The callback used to indicate the user changed the date.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDateChangedListener {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
106e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         * Called upon a date change.
107e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov         *
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param view The view associated with this listener.
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param year The year that was set.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param monthOfYear The month that was set (0-11) for compatibility
11150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         *            with {@link java.util.Calendar}.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dayOfMonth The day of the month that was set.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context) {
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context, AttributeSet attrs) {
1224243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov        this(context, attrs, R.attr.datePickerStyle);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
125617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
126617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
127617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
128617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
129617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
130617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
13360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                defStyleAttr, defStyleRes);
134518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        final int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
1350a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
136bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        a.recycle();
137bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1383053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        switch (mode) {
1393053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_CALENDAR:
1403053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1413053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
1423053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_SPINNER:
1433053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            default:
1443053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
1453053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
146bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
1470a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
1480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek != 0) {
1490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            setFirstDayOfWeek(firstDayOfWeek);
1500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
151bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
152bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1533053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
154bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1553053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerSpinnerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
156bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
157bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1583053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs,
159bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
1603053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr,
161bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                defStyleRes);
162bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
163bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
164bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
165039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * Initialize the state. If the provided values designate an inconsistent
166039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * date the values are normalized before updating the spinners.
167039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
168039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The initial year.
169039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param monthOfYear The initial month <strong>starting from zero</strong>.
170039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The initial day of the month.
171039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param onDateChangedListener How user is notified date is changed by
172039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *            user, can be null.
173039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
174039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
175039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                     OnDateChangedListener onDateChangedListener) {
176039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
177039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
17813427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov
179039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
180bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Update the current date.
181039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     *
182039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param year The year.
183039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param month The month which is <strong>starting from zero</strong>.
184039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @param dayOfMonth The day of the month.
185039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
186039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
187039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.updateDate(year, month, dayOfMonth);
188039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
189e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
190039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
191039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected year.
192039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
193039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getYear() {
194039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getYear();
195039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
1963fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
197039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
198039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected month.
199039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
200039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getMonth() {
201039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getMonth();
202039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
2034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
204039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    /**
205039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * @return The selected day of month.
206039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     */
207039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    public int getDayOfMonth() {
208039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getDayOfMonth();
209e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
210e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
211e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
212e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the minimal date supported by this {@link DatePicker} in
213e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
214e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
215e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
216e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default minimal date is 01/01/1900.
217e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
218e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
219e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The minimal supported date.
220e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
221e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMinDate() {
222bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMinDate().getTimeInMillis();
223e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
224e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
225e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
226e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the minimal date supported by this {@link NumberPicker} in
227e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
228e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
229e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
230e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param minDate The minimal supported date.
231e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
232e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMinDate(long minDate) {
233039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMinDate(minDate);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
23628104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    /**
237e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Gets the maximal date supported by this {@link DatePicker} in
238e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
239e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
240e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * <p>
241e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Note: The default maximal date is 12/31/2100.
24228104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     * <p>
24328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     *
244e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @return The maximal supported date.
245e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
246e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public long getMaxDate() {
247bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mDelegate.getMaxDate().getTimeInMillis();
248e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
249e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
250e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
251e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets the maximal date supported by this {@link DatePicker} in
252e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * milliseconds since January 1, 1970 00:00:00 in
253e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * {@link TimeZone#getDefault()} time zone.
254e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
255e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * @param maxDate The maximal supported date.
25628104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov     */
257e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setMaxDate(long maxDate) {
258039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setMaxDate(maxDate);
25928104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov    }
26028104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov
261518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    /**
262518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * Sets the callback that indicates the current date is valid.
263518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     *
264518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @param callback the callback, may be null
265518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * @hide
266518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     */
267518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public void setValidationCallback(@Nullable ValidationCallback callback) {
268518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        mDelegate.setValidationCallback(callback);
269518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    }
270518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setEnabled(boolean enabled) {
273039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        if (mDelegate.isEnabled() == enabled) {
27451c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov            return;
27551c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov        }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setEnabled(enabled);
277039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setEnabled(enabled);
27851c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    }
27951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov
28051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    @Override
28151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov    public boolean isEnabled() {
282039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.isEnabled();
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
285a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
2868a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    @Override
287a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
288039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.dispatchPopulateAccessibilityEvent(event);
2893fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    }
2903fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov
291a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
2923fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    @Override
293a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
294a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        super.onPopulateAccessibilityEventInternal(event);
295039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onPopulateAccessibilityEvent(event);
2968a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov    }
2978a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov
2988a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
299a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn    public CharSequence getAccessibilityClassName() {
300a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn        return DatePicker.class.getName();
3018a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3028a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
3038a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
304f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    protected void onConfigurationChanged(Configuration newConfig) {
305f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        super.onConfigurationChanged(newConfig);
306039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onConfigurationChanged(newConfig);
307f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov    }
308f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
30950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
3100a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Sets the first day of week.
3110a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3120a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @param firstDayOfWeek The first day of the week conforming to the
3130a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *            {@link CalendarView} APIs.
3140a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3150a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3160a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3170a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3180a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3190a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3200a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3210a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3220a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3230a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3240a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
3250a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) {
3260a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7");
3270a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
3280a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
3290a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3300a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3310a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
3320a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * Gets the first day of week.
3330a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3340a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @return The first day of the week conforming to the {@link CalendarView}
3350a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *         APIs.
3360a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SUNDAY
3370a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#MONDAY
3380a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#TUESDAY
3390a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#WEDNESDAY
3400a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#THURSDAY
3410a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#FRIDAY
3420a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @see Calendar#SATURDAY
3430a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     *
3440a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
3450a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette     */
3460a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public int getFirstDayOfWeek() {
3470a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        return mDelegate.getFirstDayOfWeek();
3480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
3490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
3500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    /**
351452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Returns whether the {@link CalendarView} is shown.
352452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <p>
353452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <strong>Note:</strong> This method returns {@code false} when the
354452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
355452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * to {@code calendar}.
356e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
357452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @return {@code true} if the calendar view is shown
3585f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarView()
359e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
360e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getCalendarViewShown() {
361039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarViewShown();
362e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
363e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
364e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
365452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Returns the {@link CalendarView} used by this picker.
366d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * <p>
367452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <strong>Note:</strong> This method returns {@code null} when the
368d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
369d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * to {@code calendar}.
3705f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     *
371452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @return the calendar view
3725f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     * @see #getCalendarViewShown()
3735f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov     */
3740a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public CalendarView getCalendarView() {
375039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getCalendarView();
3765f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    }
3775f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov
3785f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov    /**
379e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the {@link CalendarView} is shown.
380d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * <p>
381452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <strong>Note:</strong> Calling this method has no effect when the
382d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
383d25eb9fbb9d659aab5e8ea25d16cb8bcb458a1a9Alan Viverette     * to {@code calendar}.
384e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
385452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @param shown {@code true} to show the calendar view, {@code false} to
386452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     *              hide it
387e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
388e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setCalendarViewShown(boolean shown) {
389039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setCalendarViewShown(shown);
390e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
391e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
392e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
393452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Returns whether the spinners are shown.
394452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <p>
395452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * T<strong>Note:</strong> his method returns {@code false} when the
396452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
397452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * to {@code calendar}.
398e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
399452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @return {@code true} if the spinners are shown
40050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
401e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public boolean getSpinnersShown() {
402039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.getSpinnersShown();
403e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
404e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
405e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
406e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     * Sets whether the spinners are shown.
407452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * <p>
408452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * Calling this method has no effect when the
409452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
410452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * to {@code calendar}.
411e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     *
412452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     * @param shown {@code true} to show the spinners, {@code false} to hide
413452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette     *              them
414e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov     */
415e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    public void setSpinnersShown(boolean shown) {
416039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.setSpinnersShown(shown);
417039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
418039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
419039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
420039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
421d015e3454ec1271ba6e5e3e6f0e5f7459b8b09eaAlan Viverette        dispatchThawSelfOnly(container);
422039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
423039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
424039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
425039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected Parcelable onSaveInstanceState() {
426039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable superState = super.onSaveInstanceState();
427039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        return mDelegate.onSaveInstanceState(superState);
428039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    }
429039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
430039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    @Override
431039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    protected void onRestoreInstanceState(Parcelable state) {
432a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        BaseSavedState ss = (BaseSavedState) state;
433039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        super.onRestoreInstanceState(ss.getSuperState());
434039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        mDelegate.onRestoreInstanceState(ss);
435e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    }
436e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
437e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov    /**
438039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate interface that defined the public API of the DatePicker. Allows different
439039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * DatePicker implementations. This would need to be implemented by the DatePicker delegates
440039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * for the real behavior.
441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
443f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
444039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio    interface DatePickerDelegate {
445039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void init(int year, int monthOfYear, int dayOfMonth,
446039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                  OnDateChangedListener onDateChangedListener);
447f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
448039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void updateDate(int year, int month, int dayOfMonth);
449f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
450039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getYear();
451039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getMonth();
452039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        int getDayOfMonth();
453f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
4540a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        void setFirstDayOfWeek(int firstDayOfWeek);
4550a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        int getFirstDayOfWeek();
4560a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
457039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMinDate(long minDate);
458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMinDate();
459949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
460039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setMaxDate(long maxDate);
461bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        Calendar getMaxDate();
462f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
463039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setEnabled(boolean enabled);
464039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean isEnabled();
465039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        CalendarView getCalendarView();
467039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
468039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setCalendarViewShown(boolean shown);
469039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getCalendarViewShown();
470039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
471039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void setSpinnersShown(boolean shown);
472039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean getSpinnersShown();
473039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
474518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void setValidationCallback(ValidationCallback callback);
475bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
476039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onConfigurationChanged(Configuration newConfig);
477039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
478039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        Parcelable onSaveInstanceState(Parcelable superState);
479039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onRestoreInstanceState(Parcelable state);
480039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
481039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
482039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        void onPopulateAccessibilityEvent(AccessibilityEvent event);
483949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    }
484949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes
485949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes    /**
486039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * An abstract class which can be used as a start for DatePicker implementations
487f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov     */
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    abstract static class AbstractDatePickerDelegate implements DatePickerDelegate {
489039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The delegator
490039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected DatePicker mDelegator;
491039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
492039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The context
493039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Context mContext;
494039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
495039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // The current locale
496039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected Locale mCurrentLocale;
497039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
498039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        // Callbacks
499518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected OnDateChangedListener mOnDateChangedListener;
500518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected ValidationCallback mValidationCallback;
501039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
503039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
504039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
505039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
506039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
507f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov        }
508f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov
509039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
5100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            if (!locale.equals(mCurrentLocale)) {
5110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                mCurrentLocale = locale;
5120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                onLocaleChanged(locale);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
515518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
516518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        @Override
517518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        public void setValidationCallback(ValidationCallback callback) {
518518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            mValidationCallback = callback;
519518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
520518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette
521518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected void onValidationChanged(boolean valid) {
522518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            if (mValidationCallback != null) {
523518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette                mValidationCallback.onValidationChanged(valid);
524518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette            }
525518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
5260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
5270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        protected void onLocaleChanged(Locale locale) {
5280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            // Stub.
5290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    /**
533518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * A callback interface for updating input validity when the date picker
534518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette     * when included into a dialog.
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @hide
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
538518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette    public static interface ValidationCallback {
539518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        void onValidationChanged(boolean valid);
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
541bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
543039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio     * A delegate implementing the basic DatePicker
54450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
5453053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    private static class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate {
546039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
547039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final String DATE_FORMAT = "MM/dd/yyyy";
548039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
549039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final int DEFAULT_START_YEAR = 1900;
550039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
551039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final int DEFAULT_END_YEAR = 2100;
552039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
553039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
554039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
555039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_SPINNERS_SHOWN = true;
556039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
557039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private static final boolean DEFAULT_ENABLED_STATE = true;
558039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
559039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final LinearLayout mSpinners;
560039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
561039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mDaySpinner;
562039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
563039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mMonthSpinner;
564039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
565039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final NumberPicker mYearSpinner;
566039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
567039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mDaySpinnerInput;
568039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
569039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mMonthSpinnerInput;
570039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
571039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final EditText mYearSpinnerInput;
572039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
573039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final CalendarView mCalendarView;
574039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
575039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private String[] mShortMonths;
576039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
577039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
578039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
579039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private int mNumberOfMonths;
580039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
581039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mTempDate;
582039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
583039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mMinDate;
584039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
585039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mMaxDate;
586039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
587039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar mCurrentDate;
588039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
589039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
590039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
5913053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase        DatePickerSpinnerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
592039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                int defStyleAttr, int defStyleRes) {
593039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            super(delegator, context);
594039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
595039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator = delegator;
596039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mContext = context;
597039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
598039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialization based on locale
599039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(Locale.getDefault());
600039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
601039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
602039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.styleable.DatePicker, defStyleAttr, defStyleRes);
603039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
604039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    DEFAULT_SPINNERS_SHOWN);
605039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            boolean calendarViewShown = attributesArray.getBoolean(
606039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
607039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
608039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    DEFAULT_START_YEAR);
609039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
610039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
611039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
612039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            int layoutResourceId = attributesArray.getResourceId(
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    R.styleable.DatePicker_legacyLayout, R.layout.date_picker_legacy);
614039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            attributesArray.recycle();
615039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
616039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            LayoutInflater inflater = (LayoutInflater) context
617039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
618039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            inflater.inflate(layoutResourceId, mDelegator, true);
619039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
620039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            OnValueChangeListener onChangeListener = new OnValueChangeListener() {
621039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
622039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateInputState();
623039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
624039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    // take care of wrapping of days and months to update greater fields
625039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    if (picker == mDaySpinner) {
626039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
627039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        if (oldVal == maxDayOfMonth && newVal == 1) {
628039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, 1);
629039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else if (oldVal == 1 && newVal == maxDayOfMonth) {
630039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, -1);
631039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else {
632039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
633039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        }
634039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else if (picker == mMonthSpinner) {
635039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        if (oldVal == 11 && newVal == 0) {
636039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, 1);
637039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else if (oldVal == 0 && newVal == 11) {
638039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, -1);
639039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        } else {
640039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.add(Calendar.MONTH, newVal - oldVal);
641039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        }
642039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else if (picker == mYearSpinner) {
643039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mTempDate.set(Calendar.YEAR, newVal);
644039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    } else {
645039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        throw new IllegalArgumentException();
646039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    }
647039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    // now set the date to the adjusted one
648039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
649039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                            mTempDate.get(Calendar.DAY_OF_MONTH));
650039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateSpinners();
651039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateCalendarView();
652039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    notifyDateChanged();
653039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
654039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            };
655039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
656039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners = (LinearLayout) mDelegator.findViewById(R.id.pickers);
657039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
658039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // calendar view day-picker
659039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView = (CalendarView) mDelegator.findViewById(R.id.calendar_view);
660039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
661039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
662039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    setDate(year, month, monthDay);
663039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    updateSpinners();
664039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    notifyDateChanged();
665039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
666039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            });
667039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
668039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // day
669039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner = (NumberPicker) mDelegator.findViewById(R.id.day);
670039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
671039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setOnLongPressUpdateInterval(100);
672039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setOnValueChangedListener(onChangeListener);
673039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
674039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
675039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // month
676039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner = (NumberPicker) mDelegator.findViewById(R.id.month);
677039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setMinValue(0);
678039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
679039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setDisplayedValues(mShortMonths);
680039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setOnLongPressUpdateInterval(200);
681039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setOnValueChangedListener(onChangeListener);
682039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
683039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
684039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // year
685039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner = (NumberPicker) mDelegator.findViewById(R.id.year);
686039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setOnLongPressUpdateInterval(100);
687039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setOnValueChangedListener(onChangeListener);
688039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
689039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
690039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // show only what the user required but make sure we
691039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // show something and the spinners have higher priority
692039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!spinnersShown && !calendarViewShown) {
693039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setSpinnersShown(true);
694039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
695039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setSpinnersShown(spinnersShown);
696039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                setCalendarViewShown(calendarViewShown);
697039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
698039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
699039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the min date giving priority of the minDate over startYear
700039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.clear();
701039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!TextUtils.isEmpty(minDate)) {
702039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (!parseDate(minDate, mTempDate)) {
703039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.set(startYear, 0, 1);
704039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
705039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
706039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mTempDate.set(startYear, 0, 1);
707039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
708039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setMinDate(mTempDate.getTimeInMillis());
709039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
710039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the max date giving priority of the maxDate over endYear
711039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.clear();
712039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!TextUtils.isEmpty(maxDate)) {
713039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (!parseDate(maxDate, mTempDate)) {
714039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mTempDate.set(endYear, 11, 31);
715039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
716039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
717039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mTempDate.set(endYear, 11, 31);
718039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
719039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setMaxDate(mTempDate.getTimeInMillis());
720039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
721039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // initialize to current date
722039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate.setTimeInMillis(System.currentTimeMillis());
723039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
724039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    .get(Calendar.DAY_OF_MONTH), null);
725039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
726039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // re-order the number spinners to match the current date format
727039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            reorderSpinners();
728039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
729039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // accessibility
730039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setContentDescriptions();
731039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
732039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // If not explicitly specified this view is important for accessibility.
733039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
734039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
735039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
736dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root        }
737dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root
738039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
739039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void init(int year, int monthOfYear, int dayOfMonth,
740039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                         OnDateChangedListener onDateChangedListener) {
741039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(year, monthOfYear, dayOfMonth);
742039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
743039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
744039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mOnDateChangedListener = onDateChangedListener;
745039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
747039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
748039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void updateDate(int year, int month, int dayOfMonth) {
749039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (!isNewDate(year, month, dayOfMonth)) {
750039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
751039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
752039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(year, month, dayOfMonth);
753039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
754039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
755039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            notifyDateChanged();
756039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
758039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
759039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getYear() {
760039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.YEAR);
761039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
763039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
764039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getMonth() {
765039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.MONTH);
766039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
768039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
769039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public int getDayOfMonth() {
770039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCurrentDate.get(Calendar.DAY_OF_MONTH);
771039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
772039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
773039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
7740a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        public void setFirstDayOfWeek(int firstDayOfWeek) {
7750a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            mCalendarView.setFirstDayOfWeek(firstDayOfWeek);
7760a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
7770a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
7780a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        @Override
7790a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        public int getFirstDayOfWeek() {
7800a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mCalendarView.getFirstDayOfWeek();
7810a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
7820a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
7830a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        @Override
784039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setMinDate(long minDate) {
785039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.setTimeInMillis(minDate);
786039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
787039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
788039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
789039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
790039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMinDate.setTimeInMillis(minDate);
791039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setMinDate(minDate);
792039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.before(mMinDate)) {
793039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
794039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                updateCalendarView();
795039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
796039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
797039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
798039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
799039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
800bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public Calendar getMinDate() {
801bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final Calendar minDate = Calendar.getInstance();
802bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            minDate.setTimeInMillis(mCalendarView.getMinDate());
803bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return minDate;
804039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
805039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
806039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
807039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setMaxDate(long maxDate) {
808039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate.setTimeInMillis(maxDate);
809039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
810039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
811039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return;
812039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
813039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMaxDate.setTimeInMillis(maxDate);
814039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setMaxDate(maxDate);
815039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.after(mMaxDate)) {
816039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
817039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                updateCalendarView();
818039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
819039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
820039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
821039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
822039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
823bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public Calendar getMaxDate() {
824bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final Calendar maxDate = Calendar.getInstance();
825bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            maxDate.setTimeInMillis(mCalendarView.getMaxDate());
826bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return maxDate;
827039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
828039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
829039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
830039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setEnabled(boolean enabled) {
831039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setEnabled(enabled);
832039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setEnabled(enabled);
833039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setEnabled(enabled);
834039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setEnabled(enabled);
835039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mIsEnabled = enabled;
836039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
837039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
838039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
839039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean isEnabled() {
840039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mIsEnabled;
841039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
842039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
843039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
844039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public CalendarView getCalendarView() {
845039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mCalendarView;
846039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
847039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
848039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
849039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setCalendarViewShown(boolean shown) {
850039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setVisibility(shown ? VISIBLE : GONE);
851039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
852039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
853039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
854039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean getCalendarViewShown() {
855039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return (mCalendarView.getVisibility() == View.VISIBLE);
856039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
857039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
858039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
859039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void setSpinnersShown(boolean shown) {
860039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners.setVisibility(shown ? VISIBLE : GONE);
861039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
862039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
863039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
864039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean getSpinnersShown() {
865039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return mSpinners.isShown();
866039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
867039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
868039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
869039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onConfigurationChanged(Configuration newConfig) {
870039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setCurrentLocale(newConfig.locale);
871039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
872039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
873039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
874039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public Parcelable onSaveInstanceState(Parcelable superState) {
875039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
876039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
877039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
878039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
879039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onRestoreInstanceState(Parcelable state) {
880039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            SavedState ss = (SavedState) state;
881039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            setDate(ss.mYear, ss.mMonth, ss.mDay);
882039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateSpinners();
883039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            updateCalendarView();
884039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
885039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
886039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
887039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
888039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            onPopulateAccessibilityEvent(event);
889e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov            return true;
890e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov        }
891e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov
892039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
893039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
894039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
895039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String selectedDateUtterance = DateUtils.formatDateTime(mContext,
896039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mCurrentDate.getTimeInMillis(), flags);
897039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            event.getText().add(selectedDateUtterance);
898039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
899156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov
900039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
901039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Sets the current locale.
902039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
903039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param locale The current locale.
904039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
905039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        @Override
906039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        protected void setCurrentLocale(Locale locale) {
907039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            super.setCurrentLocale(locale);
908039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
909039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mTempDate = getCalendarForLocale(mTempDate, locale);
910039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMinDate = getCalendarForLocale(mMinDate, locale);
911039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMaxDate = getCalendarForLocale(mMaxDate, locale);
912039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
913039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
914039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
915039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mShortMonths = new DateFormatSymbols().getShortMonths();
916039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
917039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (usingNumericMonths()) {
918039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                // We're in a locale where a date should either be all-numeric, or all-text.
919039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                // All-text would require custom NumberPicker formatters for day and year.
920039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mShortMonths = new String[mNumberOfMonths];
921039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                for (int i = 0; i < mNumberOfMonths; ++i) {
922039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mShortMonths[i] = String.format("%d", i + 1);
923039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
924039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
925e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim        }
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
927039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
928039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Tests whether the current locale is one where there are no real month names,
929039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * such as Chinese, Japanese, or Korean locales.
930039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
931039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean usingNumericMonths() {
932039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
933039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
935039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
936039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Gets a calendar for locale bootstrapped with the value of a given calendar.
937039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
938039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param oldCalendar The old calendar.
939039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param locale The locale.
940039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
941039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
942039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (oldCalendar == null) {
943039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return Calendar.getInstance(locale);
944039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
945039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                final long currentTimeMillis = oldCalendar.getTimeInMillis();
946039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                Calendar newCalendar = Calendar.getInstance(locale);
947039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                newCalendar.setTimeInMillis(currentTimeMillis);
948039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return newCalendar;
949039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
950039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
952039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
953039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Reorders the spinners according to the date format that is
954039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * explicitly set by the user and if no such is set fall back
955039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * to the current locale's default format.
956039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
957039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void reorderSpinners() {
958039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mSpinners.removeAllViews();
959039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // We use numeric spinners for year and day, but textual months. Ask icu4c what
960039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // order the user's locale uses for that combination. http://b/7207103.
961f8abeb8457feb766fb45829f6b175a22d4814d66Elliott Hughes            String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
962039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            char[] order = ICU.getDateFormatOrder(pattern);
963039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int spinnerCount = order.length;
964039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            for (int i = 0; i < spinnerCount; i++) {
965039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                switch (order[i]) {
966039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'd':
967039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mDaySpinner);
968039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mDaySpinner, spinnerCount, i);
969039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
970039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'M':
971039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mMonthSpinner);
972039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mMonthSpinner, spinnerCount, i);
973039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
974039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    case 'y':
975039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        mSpinners.addView(mYearSpinner);
976039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        setImeOptions(mYearSpinner, spinnerCount, i);
977039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        break;
978039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    default:
979039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        throw new IllegalArgumentException(Arrays.toString(order));
980039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
981039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
982039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
984039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
985039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Parses the given <code>date</code> and in case of success sets the result
986039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * to the <code>outDate</code>.
987039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
988039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @return True if the date was parsed.
989039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
990039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean parseDate(String date, Calendar outDate) {
991039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            try {
992039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                outDate.setTime(mDateFormat.parse(date));
993039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return true;
994039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } catch (ParseException e) {
995039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
996039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                return false;
997039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
998039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
9992bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu
1000039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private boolean isNewDate(int year, int month, int dayOfMonth) {
1001039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            return (mCurrentDate.get(Calendar.YEAR) != year
1002039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
1003039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
10042bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        }
1005e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson
1006039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setDate(int year, int month, int dayOfMonth) {
1007039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCurrentDate.set(year, month, dayOfMonth);
1008039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.before(mMinDate)) {
1009039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
1010039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else if (mCurrentDate.after(mMaxDate)) {
1011039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
1012039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1013039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1014039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1015039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateSpinners() {
1016039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the spinner ranges respecting the min and max dates
1017039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mCurrentDate.equals(mMinDate)) {
1018039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1019039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
1020039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(false);
1021039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1022039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
1023039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
1024039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(false);
1025039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else if (mCurrentDate.equals(mMaxDate)) {
1026039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
1027039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1028039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(false);
1029039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1030039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
1031039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
1032039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(false);
1033039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
1034039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMinValue(1);
1035039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
1036039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mDaySpinner.setWrapSelectorWheel(true);
1037039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setDisplayedValues(null);
1038039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMinValue(0);
1039039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setMaxValue(11);
1040039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinner.setWrapSelectorWheel(true);
1041039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1042039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1043039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // make sure the month names are a zero based array
1044039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // with the months in the month spinner
1045039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            String[] displayedValues = Arrays.copyOfRange(mShortMonths,
1046039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
1047039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setDisplayedValues(displayedValues);
1048039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1049039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // year spinner range does not change based on the current date
1050039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
1051039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
1052039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setWrapSelectorWheel(false);
1053039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1054039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // set the spinner values
1055039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
1056039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
1057039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
1058039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1059039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (usingNumericMonths()) {
1060039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
1061039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1062039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1063039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1064039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1065039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Updates the calendar view with the current date.
1066039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1067039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateCalendarView() {
1068039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
1069039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1070039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1071039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1072039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1073039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Notifies the listener, if such, for a change in the selected date.
1074039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1075039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void notifyDateChanged() {
1076039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
1077039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (mOnDateChangedListener != null) {
1078039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
1079039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                        getDayOfMonth());
1080039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1081039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1082039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1083039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        /**
1084039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * Sets the IME options for a spinner based on its ordering.
1085039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         *
1086039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinner The spinner.
1087039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinnerCount The total spinner count.
1088039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         * @param spinnerIndex The index of the given spinner.
1089039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio         */
1090039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
1091039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            final int imeOptions;
1092039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (spinnerIndex < spinnerCount - 1) {
1093039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                imeOptions = EditorInfo.IME_ACTION_NEXT;
1094039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            } else {
1095039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                imeOptions = EditorInfo.IME_ACTION_DONE;
1096039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1097039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
1098039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            input.setImeOptions(imeOptions);
1099039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1100039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1101039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void setContentDescriptions() {
1102039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Day
1103039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mDaySpinner, R.id.increment,
1104039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_day_button);
1105039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mDaySpinner, R.id.decrement,
1106039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_day_button);
1107039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Month
1108039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mMonthSpinner, R.id.increment,
1109039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_month_button);
1110039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mMonthSpinner, R.id.decrement,
1111039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_month_button);
1112039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Year
1113039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mYearSpinner, R.id.increment,
1114039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_increment_year_button);
1115039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            trySetContentDescription(mYearSpinner, R.id.decrement,
1116039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    R.string.date_picker_decrement_year_button);
1117039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1118039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1119039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void trySetContentDescription(View root, int viewId, int contDescResId) {
1120039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            View target = root.findViewById(viewId);
1121039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (target != null) {
1122039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                target.setContentDescription(mContext.getString(contDescResId));
1123039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            }
1124039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        }
1125039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio
1126039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio        private void updateInputState() {
1127039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // Make sure that if the user changes the value and the IME is active
1128039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // for one of the inputs if this widget, the IME is closed. If the user
1129039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // changed the value via the IME and there is a next input the IME will
1130039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // be shown, otherwise the user chose another means of changing the
1131039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            // value and having the IME up makes no sense.
1132039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
1133039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio            if (inputMethodManager != null) {
1134039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                if (inputMethodManager.isActive(mYearSpinnerInput)) {
1135039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mYearSpinnerInput.clearFocus();
1136039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1137039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
1138039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mMonthSpinnerInput.clearFocus();
1139039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1140039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
1141039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    mDaySpinnerInput.clearFocus();
1142039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
1143039a784ea3c24625b74084be18530f81dabd4bbbFabrice Di Meglio                }
11446304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov            }
11456304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov        }
11466304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov    }
11476304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov
1148a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov    /**
114950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     * Class for managing state storing/restoring.
115050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov     */
115150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov    private static class SavedState extends BaseSavedState {
115250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
115350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mYear;
115450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
115550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mMonth;
115650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
115750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private final int mDay;
115850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
115950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        /**
116050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         * Constructor called from {@link DatePicker#onSaveInstanceState()}
116150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         */
116250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private SavedState(Parcelable superState, int year, int month, int day) {
116350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super(superState);
116450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mYear = year;
116550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mMonth = month;
116650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mDay = day;
116750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        }
116850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
116950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        /**
117050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         * Constructor called from {@link #CREATOR}
117150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov         */
117250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        private SavedState(Parcel in) {
117350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super(in);
117450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mYear = in.readInt();
117550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mMonth = in.readInt();
117650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            mDay = in.readInt();
1177e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson        }
117850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
117950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        @Override
118050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        public void writeToParcel(Parcel dest, int flags) {
118150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            super.writeToParcel(dest, flags);
118250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mYear);
118350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mMonth);
118450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            dest.writeInt(mDay);
118550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        }
118650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
118750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        @SuppressWarnings("all")
118850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        // suppress unused and hiding
118950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
119050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
119150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            public SavedState createFromParcel(Parcel in) {
119250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov                return new SavedState(in);
119350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            }
119450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov
119550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            public SavedState[] newArray(int size) {
119650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov                return new SavedState[size];
119750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov            }
119850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov        };
1199e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson    }
12003fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov}
1201