blob: f2fc617ccc33ea607576f423755e73eb4a4e14d8 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.widget;
18
Alan Viverette646a0f82015-03-18 13:24:07 -070019import android.annotation.NonNull;
Alan Viverette518ff0d2014-08-15 14:20:35 -070020import android.annotation.Nullable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.annotation.Widget;
22import android.content.Context;
Svetoslav Ganovf5926962011-07-12 12:26:20 -070023import android.content.res.Configuration;
Svetoslav Ganov4243dc32011-01-18 19:39:57 -080024import android.content.res.TypedArray;
Alan Viverette6b3f85f2016-03-01 16:48:04 -050025import android.os.Parcel;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.Parcelable;
Alan Viverette6b3f85f2016-03-01 16:48:04 -050027import android.os.Parcelable.Creator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.util.AttributeSet;
Alan Viverette6b3f85f2016-03-01 16:48:04 -050029import android.view.View;
Svetoslav Ganov8a2a8952011-01-27 17:40:13 -080030import android.view.accessibility.AccessibilityEvent;
Svetoslav Ganova53efe92011-09-08 18:08:36 -070031import com.android.internal.R;
32
Svetoslav Ganovf5926962011-07-12 12:26:20 -070033import java.util.Locale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
Alan Viveretteb3f24632015-10-22 16:01:48 -040035import libcore.icu.LocaleData;
36
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037/**
Alan Viverette646a0f82015-03-18 13:24:07 -070038 * A widget for selecting the time of day, in either 24-hour or AM/PM mode.
Alan Viverette51344782014-07-16 17:39:27 -070039 * <p>
Alan Viverette646a0f82015-03-18 13:24:07 -070040 * For a dialog using this view, see {@link android.app.TimePickerDialog}. See
41 * the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
42 * guide for more information.
43 *
44 * @attr ref android.R.styleable#TimePicker_timePickerMode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 */
46@Widget
47public class TimePicker extends FrameLayout {
Chet Haase3053b2f2014-08-06 07:51:50 -070048 private static final int MODE_SPINNER = 1;
49 private static final int MODE_CLOCK = 2;
50
Alan Viverette51344782014-07-16 17:39:27 -070051 private final TimePickerDelegate mDelegate;
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -070052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 /**
54 * The callback interface used to indicate the time has been adjusted.
55 */
56 public interface OnTimeChangedListener {
57
58 /**
59 * @param view The view associated with this listener.
60 * @param hourOfDay The current hour.
61 * @param minute The current minute.
62 */
63 void onTimeChanged(TimePicker view, int hourOfDay, int minute);
64 }
65
66 public TimePicker(Context context) {
67 this(context, null);
68 }
Svetoslav Ganov4243dc32011-01-18 19:39:57 -080069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 public TimePicker(Context context, AttributeSet attrs) {
Svetoslav Ganov4243dc32011-01-18 19:39:57 -080071 this(context, attrs, R.attr.timePickerStyle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 }
73
Alan Viverette617feb92013-09-09 18:09:13 -070074 public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
75 this(context, attrs, defStyleAttr, 0);
76 }
77
78 public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
79 super(context, attrs, defStyleAttr, defStyleRes);
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -070080
Alan Viverette51344782014-07-16 17:39:27 -070081 final TypedArray a = context.obtainStyledAttributes(
82 attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
Alan Viverette518ff0d2014-08-15 14:20:35 -070083 final int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER);
Fabrice Di Megliodfaa6c72014-07-10 19:33:33 -070084 a.recycle();
85
Chet Haase3053b2f2014-08-06 07:51:50 -070086 switch (mode) {
87 case MODE_CLOCK:
Alan Viverettedaf33ed2014-10-23 13:34:17 -070088 mDelegate = new TimePickerClockDelegate(
Chet Haase3053b2f2014-08-06 07:51:50 -070089 this, context, attrs, defStyleAttr, defStyleRes);
90 break;
91 case MODE_SPINNER:
92 default:
Alan Viverettedaf33ed2014-10-23 13:34:17 -070093 mDelegate = new TimePickerSpinnerDelegate(
Chet Haase3053b2f2014-08-06 07:51:50 -070094 this, context, attrs, defStyleAttr, defStyleRes);
95 break;
Fabrice Di Megliodfaa6c72014-07-10 19:33:33 -070096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 }
Svetoslav Ganov50f34d12010-12-03 16:05:40 -080098
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -070099 /**
Alan Viverette646a0f82015-03-18 13:24:07 -0700100 * Sets the currently selected hour using 24-hour time.
101 *
102 * @param hour the hour to set, in the range (0-23)
103 * @see #getHour()
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700104 */
Alan Viverette646a0f82015-03-18 13:24:07 -0700105 public void setHour(int hour) {
Alan Viverette4420ae82015-11-16 16:10:56 -0500106 mDelegate.setHour(hour);
Fabrice Di Meglio64902bd2013-08-15 17:49:49 -0700107 }
108
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700109 /**
Alan Viverette646a0f82015-03-18 13:24:07 -0700110 * Returns the currently selected hour using 24-hour time.
111 *
112 * @return the currently selected hour, in the range (0-23)
113 * @see #setHour(int)
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700114 */
Alan Viverette646a0f82015-03-18 13:24:07 -0700115 public int getHour() {
Alan Viverette4420ae82015-11-16 16:10:56 -0500116 return mDelegate.getHour();
Alan Viverette646a0f82015-03-18 13:24:07 -0700117 }
118
119 /**
120 * Sets the currently selected minute..
121 *
122 * @param minute the minute to set, in the range (0-59)
123 * @see #getMinute()
124 */
125 public void setMinute(int minute) {
Alan Viverette4420ae82015-11-16 16:10:56 -0500126 mDelegate.setMinute(minute);
Alan Viverette646a0f82015-03-18 13:24:07 -0700127 }
128
129 /**
130 * Returns the currently selected minute.
131 *
132 * @return the currently selected minute, in the range (0-59)
133 * @see #setMinute(int)
134 */
135 public int getMinute() {
Alan Viverette4420ae82015-11-16 16:10:56 -0500136 return mDelegate.getMinute();
Alan Viverette646a0f82015-03-18 13:24:07 -0700137 }
138
139 /**
140 * Sets the current hour.
141 *
142 * @deprecated Use {@link #setHour(int)}
143 */
144 @Deprecated
145 public void setCurrentHour(@NonNull Integer currentHour) {
146 setHour(currentHour);
147 }
148
149 /**
150 * @return the current hour in the range (0-23)
151 * @deprecated Use {@link #getHour()}
152 */
153 @NonNull
154 @Deprecated
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700155 public Integer getCurrentHour() {
Alan Viverette4420ae82015-11-16 16:10:56 -0500156 return mDelegate.getHour();
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700157 }
Fabrice Di Meglio64902bd2013-08-15 17:49:49 -0700158
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700159 /**
160 * Set the current minute (0-59).
Alan Viverette646a0f82015-03-18 13:24:07 -0700161 *
162 * @deprecated Use {@link #setMinute(int)}
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700163 */
Alan Viverette646a0f82015-03-18 13:24:07 -0700164 @Deprecated
165 public void setCurrentMinute(@NonNull Integer currentMinute) {
Alan Viverette4420ae82015-11-16 16:10:56 -0500166 mDelegate.setMinute(currentMinute);
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700167 }
168
169 /**
Alan Viverette646a0f82015-03-18 13:24:07 -0700170 * @return the current minute
171 * @deprecated Use {@link #getMinute()}
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700172 */
Alan Viverette646a0f82015-03-18 13:24:07 -0700173 @NonNull
174 @Deprecated
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700175 public Integer getCurrentMinute() {
Alan Viverette4420ae82015-11-16 16:10:56 -0500176 return mDelegate.getMinute();
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700177 }
178
179 /**
Alan Viverette646a0f82015-03-18 13:24:07 -0700180 * Sets whether this widget displays time in 24-hour mode or 12-hour mode
181 * with an AM/PM picker.
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700182 *
Alan Viverette646a0f82015-03-18 13:24:07 -0700183 * @param is24HourView {@code true} to display in 24-hour mode,
184 * {@code false} for 12-hour mode with AM/PM
185 * @see #is24HourView()
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700186 */
Alan Viverette646a0f82015-03-18 13:24:07 -0700187 public void setIs24HourView(@NonNull Boolean is24HourView) {
188 if (is24HourView == null) {
189 return;
190 }
191
Alan Viverette4420ae82015-11-16 16:10:56 -0500192 mDelegate.setIs24Hour(is24HourView);
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700193 }
194
195 /**
Alan Viverette646a0f82015-03-18 13:24:07 -0700196 * @return {@code true} if this widget displays time in 24-hour mode,
197 * {@code false} otherwise}
198 * @see #setIs24HourView(Boolean)
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700199 */
200 public boolean is24HourView() {
Alan Viverette4420ae82015-11-16 16:10:56 -0500201 return mDelegate.is24Hour();
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700202 }
203
204 /**
205 * Set the callback that indicates the time has been adjusted by the user.
206 *
207 * @param onTimeChangedListener the callback, should not be null.
208 */
209 public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
210 mDelegate.setOnTimeChangedListener(onTimeChangedListener);
Fabrice Di Meglio64902bd2013-08-15 17:49:49 -0700211 }
212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 @Override
214 public void setEnabled(boolean enabled) {
215 super.setEnabled(enabled);
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700216 mDelegate.setEnabled(enabled);
Svetoslav Ganov51c52ed2010-12-28 13:45:03 -0800217 }
218
219 @Override
220 public boolean isEnabled() {
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700221 return mDelegate.isEnabled();
222 }
223
224 @Override
225 public int getBaseline() {
226 return mDelegate.getBaseline();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 }
228
Svetoslav Ganovf5926962011-07-12 12:26:20 -0700229 @Override
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700230 protected Parcelable onSaveInstanceState() {
231 Parcelable superState = super.onSaveInstanceState();
232 return mDelegate.onSaveInstanceState(superState);
233 }
234
235 @Override
236 protected void onRestoreInstanceState(Parcelable state) {
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -0700237 BaseSavedState ss = (BaseSavedState) state;
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700238 super.onRestoreInstanceState(ss.getSuperState());
239 mDelegate.onRestoreInstanceState(ss);
240 }
241
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800242 @Override
243 public CharSequence getAccessibilityClassName() {
244 return TimePicker.class.getName();
245 }
246
Alan Viverettea54956a2015-01-07 16:05:02 -0800247 /** @hide */
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700248 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800249 public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700250 return mDelegate.dispatchPopulateAccessibilityEvent(event);
251 }
252
Svetoslav Ganovf5926962011-07-12 12:26:20 -0700253 /**
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700254 * A delegate interface that defined the public API of the TimePicker. Allows different
255 * TimePicker implementations. This would need to be implemented by the TimePicker delegates
256 * for the real behavior.
Svetoslav Ganovf5926962011-07-12 12:26:20 -0700257 */
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -0700258 interface TimePickerDelegate {
Alan Viverette4420ae82015-11-16 16:10:56 -0500259 void setHour(int hour);
260 int getHour();
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700261
Alan Viverette4420ae82015-11-16 16:10:56 -0500262 void setMinute(int minute);
263 int getMinute();
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700264
Alan Viverette4420ae82015-11-16 16:10:56 -0500265 void setIs24Hour(boolean is24Hour);
266 boolean is24Hour();
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700267
268 void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
269
270 void setEnabled(boolean enabled);
271 boolean isEnabled();
272
273 int getBaseline();
274
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700275 Parcelable onSaveInstanceState(Parcelable superState);
276 void onRestoreInstanceState(Parcelable state);
277
278 boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
279 void onPopulateAccessibilityEvent(AccessibilityEvent event);
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700280 }
281
Alan Viveretteb3f24632015-10-22 16:01:48 -0400282 static String[] getAmPmStrings(Context context) {
283 final Locale locale = context.getResources().getConfiguration().locale;
284 final LocaleData d = LocaleData.get(locale);
285
286 final String[] result = new String[2];
287 result[0] = d.amPm[0].length() > 4 ? d.narrowAm : d.amPm[0];
288 result[1] = d.amPm[1].length() > 4 ? d.narrowPm : d.amPm[1];
289 return result;
290 }
291
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -0700292 /**
293 * An abstract class which can be used as a start for TimePicker implementations
294 */
295 abstract static class AbstractTimePickerDelegate implements TimePickerDelegate {
Alan Viverette4420ae82015-11-16 16:10:56 -0500296 protected final TimePicker mDelegator;
297 protected final Context mContext;
298 protected final Locale mLocale;
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700299
Alan Viverette518ff0d2014-08-15 14:20:35 -0700300 protected OnTimeChangedListener mOnTimeChangedListener;
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700301
Alan Viverette4420ae82015-11-16 16:10:56 -0500302 public AbstractTimePickerDelegate(@NonNull TimePicker delegator, @NonNull Context context) {
Fabrice Di Meglio9e4009e2013-08-19 13:16:46 -0700303 mDelegator = delegator;
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -0700304 mContext = context;
Alan Viverette4420ae82015-11-16 16:10:56 -0500305 mLocale = context.getResources().getConfiguration().locale;
Alan Viverette518ff0d2014-08-15 14:20:35 -0700306 }
Alan Viverette6b3f85f2016-03-01 16:48:04 -0500307
308 protected static class SavedState extends View.BaseSavedState {
309 private final int mHour;
310 private final int mMinute;
311 private final boolean mIs24HourMode;
312 private final int mCurrentItemShowing;
313
314 public SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode) {
315 this(superState, hour, minute, is24HourMode, 0);
316 }
317
318 public SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode,
319 int currentItemShowing) {
320 super(superState);
321 mHour = hour;
322 mMinute = minute;
323 mIs24HourMode = is24HourMode;
324 mCurrentItemShowing = currentItemShowing;
325 }
326
327 private SavedState(Parcel in) {
328 super(in);
329 mHour = in.readInt();
330 mMinute = in.readInt();
331 mIs24HourMode = (in.readInt() == 1);
332 mCurrentItemShowing = in.readInt();
333 }
334
335 public int getHour() {
336 return mHour;
337 }
338
339 public int getMinute() {
340 return mMinute;
341 }
342
343 public boolean is24HourMode() {
344 return mIs24HourMode;
345 }
346
347 public int getCurrentItemShowing() {
348 return mCurrentItemShowing;
349 }
350
351 @Override
352 public void writeToParcel(Parcel dest, int flags) {
353 super.writeToParcel(dest, flags);
354 dest.writeInt(mHour);
355 dest.writeInt(mMinute);
356 dest.writeInt(mIs24HourMode ? 1 : 0);
357 dest.writeInt(mCurrentItemShowing);
358 }
359
360 @SuppressWarnings({"unused", "hiding"})
361 public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
362 public SavedState createFromParcel(Parcel in) {
363 return new SavedState(in);
364 }
365
366 public SavedState[] newArray(int size) {
367 return new SavedState[size];
368 }
369 };
370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372}