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
19f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viveretteimport com.android.internal.R;
20f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette
218817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport android.annotation.IntDef;
22f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viveretteimport android.annotation.IntRange;
23646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viveretteimport android.annotation.NonNull;
248817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport android.annotation.TestApi;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.Widget;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
274243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganovimport android.content.res.TypedArray;
286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.os.Parcel;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
31f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viveretteimport android.util.MathUtils;
326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.view.View;
338a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
34a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov
358817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport java.lang.annotation.Retention;
368817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viveretteimport java.lang.annotation.RetentionPolicy;
37f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport java.util.Locale;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viveretteimport libcore.icu.LocaleData;
40b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
42646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette * A widget for selecting the time of day, in either 24-hour or AM/PM mode.
435134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette * <p>
44646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette * For a dialog using this view, see {@link android.app.TimePickerDialog}. See
45646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette * the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
46646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette * guide for more information.
47646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette *
48646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette * @attr ref android.R.styleable#TimePicker_timePickerMode
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class TimePicker extends FrameLayout {
528817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /**
538817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * Presentation mode for the Holo-style time picker that uses a set of
548817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * {@link android.widget.NumberPicker}s.
558817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     *
568817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @see #getMode()
578817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @hide Visible for testing only.
588817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     */
598817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TestApi
608817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public static final int MODE_SPINNER = 1;
618817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
628817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /**
638817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * Presentation mode for the Material-style time picker that uses a clock
648817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * face.
658817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     *
668817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @see #getMode()
678817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @hide Visible for testing only.
688817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     */
698817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TestApi
708817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public static final int MODE_CLOCK = 2;
718817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
728817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /** @hide */
738817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @IntDef({MODE_SPINNER, MODE_CLOCK})
748817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @Retention(RetentionPolicy.SOURCE)
758817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public @interface TimePickerMode {}
763053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase
775134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette    private final TimePickerDelegate mDelegate;
78eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio
798817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TimePickerMode
808817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    private final int mMode;
818817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
829e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
839e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     * The callback interface used to indicate the time has been adjusted.
849e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
859e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public interface OnTimeChangedListener {
869e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
879e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        /**
889e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio         * @param view The view associated with this listener.
899e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio         * @param hourOfDay The current hour.
909e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio         * @param minute The current minute.
919e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio         */
929e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        void onTimeChanged(TimePicker view, int hourOfDay, int minute);
939e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
949e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
959e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public TimePicker(Context context) {
969e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        this(context, null);
979e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
989e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
999e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public TimePicker(Context context, AttributeSet attrs) {
1009e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        this(context, attrs, R.attr.timePickerStyle);
1019e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
1029e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
103617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
104617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
105617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
106617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
107617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
108617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
109eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio
1105134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette        final TypedArray a = context.obtainStyledAttributes(
1115134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette                attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
1128817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        final boolean isDialogMode = a.getBoolean(R.styleable.TimePicker_dialogMode, false);
1138817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        final int requestedMode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER);
114dfaa6c7439d1506b2450005a6c1e0be6771eb9e5Fabrice Di Meglio        a.recycle();
115dfaa6c7439d1506b2450005a6c1e0be6771eb9e5Fabrice Di Meglio
1168817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        if (requestedMode == MODE_CLOCK && isDialogMode) {
1178817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            // You want MODE_CLOCK? YOU CAN'T HANDLE MODE_CLOCK! Well, maybe
1188817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            // you can depending on your screen size. Let's check...
1198817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            mMode = context.getResources().getInteger(R.integer.time_picker_mode);
1208817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        } else {
1218817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette            mMode = requestedMode;
1228817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        }
1238817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
1248817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        switch (mMode) {
1253053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_CLOCK:
126daf33ed85353ab7d7a7668dd0e3f9a66f0d5583fAlan Viverette                mDelegate = new TimePickerClockDelegate(
1273053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                        this, context, attrs, defStyleAttr, defStyleRes);
1283053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
1293053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            case MODE_SPINNER:
1303053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase            default:
131daf33ed85353ab7d7a7668dd0e3f9a66f0d5583fAlan Viverette                mDelegate = new TimePickerSpinnerDelegate(
1323053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                        this, context, attrs, defStyleAttr, defStyleRes);
1333053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase                break;
134dfaa6c7439d1506b2450005a6c1e0be6771eb9e5Fabrice Di Meglio        }
1359e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
1369e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
1379e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
1388817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @return the picker's presentation mode, one of {@link #MODE_CLOCK} or
1398817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     *         {@link #MODE_SPINNER}
1408817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @attr ref android.R.styleable#TimePicker_timePickerMode
1418817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     * @hide Visible for testing only.
1428817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette     */
1438817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TimePickerMode
1448817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    @TestApi
1458817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    public int getMode() {
1468817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette        return mMode;
1478817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    }
1488817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette
1498817aa93392b7a46402eacd7a3b252d1da6c7225Alan Viverette    /**
150646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * Sets the currently selected hour using 24-hour time.
151646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *
152646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @param hour the hour to set, in the range (0-23)
153646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @see #getHour()
154646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     */
155f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette    public void setHour(@IntRange(from = 0, to = 23) int hour) {
156f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        mDelegate.setHour(MathUtils.constrain(hour, 0, 23));
157646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    }
158646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette
159646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    /**
160646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * Returns the currently selected hour using 24-hour time.
161646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *
162646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @return the currently selected hour, in the range (0-23)
163646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @see #setHour(int)
164646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     */
165646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    public int getHour() {
1664420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        return mDelegate.getHour();
167646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    }
168646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette
169646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    /**
170f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * Sets the currently selected minute.
171646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *
172646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @param minute the minute to set, in the range (0-59)
173646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @see #getMinute()
1749e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
175f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette    public void setMinute(@IntRange(from = 0, to = 59) int minute) {
176f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        mDelegate.setMinute(MathUtils.constrain(minute, 0, 59));
1779e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
1789e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
1799e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
180646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * Returns the currently selected minute.
181646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *
182646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @return the currently selected minute, in the range (0-59)
183646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @see #setMinute(int)
1849e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
185646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    public int getMinute() {
1864420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        return mDelegate.getMinute();
187646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    }
188646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette
189646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    /**
190f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * Sets the currently selected hour using 24-hour time.
191646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *
192f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * @param currentHour the hour to set, in the range (0-23)
193646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @deprecated Use {@link #setHour(int)}
194646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     */
195646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    @Deprecated
196646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    public void setCurrentHour(@NonNull Integer currentHour) {
197646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette        setHour(currentHour);
198646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    }
199646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette
200646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    /**
201f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * @return the currently selected hour, in the range (0-23)
202646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @deprecated Use {@link #getHour()}
203646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     */
204646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    @NonNull
205646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    @Deprecated
2069e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public Integer getCurrentHour() {
207f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        return getHour();
2089e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2099e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
2109e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
211f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * Sets the currently selected minute.
212646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *
213f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * @param currentMinute the minute to set, in the range (0-59)
214646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @deprecated Use {@link #setMinute(int)}
2159e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
216646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    @Deprecated
217646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    public void setCurrentMinute(@NonNull Integer currentMinute) {
218f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        setMinute(currentMinute);
2199e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2209e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
2219e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
222f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette     * @return the currently selected minute, in the range (0-59)
223646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @deprecated Use {@link #getMinute()}
2249e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
225646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    @NonNull
226646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    @Deprecated
2279e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public Integer getCurrentMinute() {
228f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        return getMinute();
2299e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2309e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
2319e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
232646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * Sets whether this widget displays time in 24-hour mode or 12-hour mode
233646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * with an AM/PM picker.
2349e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     *
235646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @param is24HourView {@code true} to display in 24-hour mode,
236646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *                     {@code false} for 12-hour mode with AM/PM
237646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @see #is24HourView()
2389e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
239646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette    public void setIs24HourView(@NonNull Boolean is24HourView) {
240646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette        if (is24HourView == null) {
241646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette            return;
242646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette        }
243646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette
2444420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        mDelegate.setIs24Hour(is24HourView);
2459e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2469e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
2479e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
248646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @return {@code true} if this widget displays time in 24-hour mode,
249646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     *         {@code false} otherwise}
250646a0f8e0d0a9f94a5969d09a498f5de5fe40a88Alan Viverette     * @see #setIs24HourView(Boolean)
2519e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
2529e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public boolean is24HourView() {
2534420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        return mDelegate.is24Hour();
2549e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2554243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2579e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     * Set the callback that indicates the time has been adjusted by the user.
2589e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     *
2599e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     * @param onTimeChangedListener the callback, should not be null.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2619e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
2629e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        mDelegate.setOnTimeChangedListener(onTimeChangedListener);
2639e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2649e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
2659e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
2669e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public void setEnabled(boolean enabled) {
2679e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        super.setEnabled(enabled);
2689e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        mDelegate.setEnabled(enabled);
2699e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2704243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov
2719e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
2729e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public boolean isEnabled() {
2739e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        return mDelegate.isEnabled();
2749e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2754243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov
2769e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
2779e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    public int getBaseline() {
2789e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        return mDelegate.getBaseline();
2799e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
2829e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    protected Parcelable onSaveInstanceState() {
2839e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        Parcelable superState = super.onSaveInstanceState();
2849e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        return mDelegate.onSaveInstanceState(superState);
2859e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2864243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov
2879e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
2889e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    protected void onRestoreInstanceState(Parcelable state) {
289eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio        BaseSavedState ss = (BaseSavedState) state;
2909e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        super.onRestoreInstanceState(ss.getSuperState());
2919e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        mDelegate.onRestoreInstanceState(ss);
2929e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2934243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov
2949e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
295a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn    public CharSequence getAccessibilityClassName() {
296a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn        return TimePicker.class.getName();
2979e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
2986304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov
299a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    /** @hide */
3009e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    @Override
301a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
302a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn        return mDelegate.dispatchPopulateAccessibilityEvent(event);
3039e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
3049e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
3059e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    /**
3069e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     * A delegate interface that defined the public API of the TimePicker. Allows different
3079e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     * TimePicker implementations. This would need to be implemented by the TimePicker delegates
3089e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     * for the real behavior.
3099e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio     */
310eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio    interface TimePickerDelegate {
311f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        void setHour(@IntRange(from = 0, to = 23) int hour);
3124420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        int getHour();
313206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov
314f0ac2ba9f4bf7b0ea3235999dde3b657a1023d76Alan Viverette        void setMinute(@IntRange(from = 0, to = 59) int minute);
3154420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        int getMinute();
3164243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov
3174420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        void setIs24Hour(boolean is24Hour);
3184420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        boolean is24Hour();
319206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov
3209e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
32151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov
3229e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        void setEnabled(boolean enabled);
3239e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        boolean isEnabled();
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        int getBaseline();
3268a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov
3279e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        Parcelable onSaveInstanceState(Parcelable superState);
3289e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        void onRestoreInstanceState(Parcelable state);
3299e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
3309e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
3319e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio        void onPopulateAccessibilityEvent(AccessibilityEvent event);
3329e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio    }
33364902bd89ea0630a59eb61345061002e9895af84Fabrice Di Meglio
334b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette    static String[] getAmPmStrings(Context context) {
335b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette        final Locale locale = context.getResources().getConfiguration().locale;
336b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette        final LocaleData d = LocaleData.get(locale);
337b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette
338b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette        final String[] result = new String[2];
339b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette        result[0] = d.amPm[0].length() > 4 ? d.narrowAm : d.amPm[0];
340b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette        result[1] = d.amPm[1].length() > 4 ? d.narrowPm : d.amPm[1];
341b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette        return result;
342b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette    }
343b3f24639902e71d4da3b2aa4eff25e75e9ce7711Alan Viverette
344eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio    /**
345eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio     * An abstract class which can be used as a start for TimePicker implementations
346eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio     */
347eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio    abstract static class AbstractTimePickerDelegate implements TimePickerDelegate {
3484420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        protected final TimePicker mDelegator;
3494420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        protected final Context mContext;
3504420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        protected final Locale mLocale;
3519e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio
352518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        protected OnTimeChangedListener mOnTimeChangedListener;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3544420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette        public AbstractTimePickerDelegate(@NonNull TimePicker delegator, @NonNull Context context) {
3559e4009ea150a7020fb8cf315281679979e67e762Fabrice Di Meglio            mDelegator = delegator;
356eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio            mContext = context;
3574420ae875de711a91dc10f7f4dd5a9cc62221ac8Alan Viverette            mLocale = context.getResources().getConfiguration().locale;
358518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        }
3596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        protected static class SavedState extends View.BaseSavedState {
3616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mHour;
3626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mMinute;
3636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final boolean mIs24HourMode;
3646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private final int mCurrentItemShowing;
3656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode) {
3676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                this(superState, hour, minute, is24HourMode, 0);
3686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
3696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode,
3716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    int currentItemShowing) {
3726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                super(superState);
3736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mHour = hour;
3746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMinute = minute;
3756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mIs24HourMode = is24HourMode;
3766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mCurrentItemShowing = currentItemShowing;
3776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
3786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            private SavedState(Parcel in) {
3806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                super(in);
3816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mHour = in.readInt();
3826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMinute = in.readInt();
3836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mIs24HourMode = (in.readInt() == 1);
3846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mCurrentItemShowing = in.readInt();
3856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
3866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getHour() {
3886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mHour;
3896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
3906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getMinute() {
3926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mMinute;
3936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
3946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public boolean is24HourMode() {
3966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mIs24HourMode;
3976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
3986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public int getCurrentItemShowing() {
4006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                return mCurrentItemShowing;
4016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
4026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            @Override
4046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public void writeToParcel(Parcel dest, int flags) {
4056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                super.writeToParcel(dest, flags);
4066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mHour);
4076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mMinute);
4086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mIs24HourMode ? 1 : 0);
4096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                dest.writeInt(mCurrentItemShowing);
4106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
4116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            @SuppressWarnings({"unused", "hiding"})
4136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
4146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                public SavedState createFromParcel(Parcel in) {
4156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    return new SavedState(in);
4166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                }
4176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                public SavedState[] newArray(int size) {
4196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    return new SavedState[size];
4206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                }
4216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            };
4226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
4233fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov    }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
425