1 /* 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 17 package android.widget; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.Widget; 22 import android.content.Context; 23 import android.content.res.Configuration; 24 import android.content.res.TypedArray; 25 import android.os.Parcelable; 26 import android.util.AttributeSet; 27 import android.view.accessibility.AccessibilityEvent; 28 import com.android.internal.R; 29 30 import java.util.Locale; 31 32 /** 33 * A widget for selecting the time of day, in either 24-hour or AM/PM mode. 34 * <p> 35 * For a dialog using this view, see {@link android.app.TimePickerDialog}. See 36 * the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> 37 * guide for more information. 38 * 39 * @attr ref android.R.styleable#TimePicker_timePickerMode 40 */ 41 @Widget 42 public class TimePicker extends FrameLayout { 43 private static final int MODE_SPINNER = 1; 44 private static final int MODE_CLOCK = 2; 45 46 private final TimePickerDelegate mDelegate; 47 48 /** 49 * The callback interface used to indicate the time has been adjusted. 50 */ 51 public interface OnTimeChangedListener { 52 53 /** 54 * @param view The view associated with this listener. 55 * @param hourOfDay The current hour. 56 * @param minute The current minute. 57 */ onTimeChanged(TimePicker view, int hourOfDay, int minute)58 void onTimeChanged(TimePicker view, int hourOfDay, int minute); 59 } 60 TimePicker(Context context)61 public TimePicker(Context context) { 62 this(context, null); 63 } 64 TimePicker(Context context, AttributeSet attrs)65 public TimePicker(Context context, AttributeSet attrs) { 66 this(context, attrs, R.attr.timePickerStyle); 67 } 68 TimePicker(Context context, AttributeSet attrs, int defStyleAttr)69 public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) { 70 this(context, attrs, defStyleAttr, 0); 71 } 72 TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)73 public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 74 super(context, attrs, defStyleAttr, defStyleRes); 75 76 final TypedArray a = context.obtainStyledAttributes( 77 attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes); 78 final int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER); 79 a.recycle(); 80 81 switch (mode) { 82 case MODE_CLOCK: 83 mDelegate = new TimePickerClockDelegate( 84 this, context, attrs, defStyleAttr, defStyleRes); 85 break; 86 case MODE_SPINNER: 87 default: 88 mDelegate = new TimePickerSpinnerDelegate( 89 this, context, attrs, defStyleAttr, defStyleRes); 90 break; 91 } 92 } 93 94 /** 95 * Sets the currently selected hour using 24-hour time. 96 * 97 * @param hour the hour to set, in the range (0-23) 98 * @see #getHour() 99 */ setHour(int hour)100 public void setHour(int hour) { 101 mDelegate.setCurrentHour(hour); 102 } 103 104 /** 105 * Returns the currently selected hour using 24-hour time. 106 * 107 * @return the currently selected hour, in the range (0-23) 108 * @see #setHour(int) 109 */ getHour()110 public int getHour() { 111 return mDelegate.getCurrentHour(); 112 } 113 114 /** 115 * Sets the currently selected minute.. 116 * 117 * @param minute the minute to set, in the range (0-59) 118 * @see #getMinute() 119 */ setMinute(int minute)120 public void setMinute(int minute) { 121 mDelegate.setCurrentMinute(minute); 122 } 123 124 /** 125 * Returns the currently selected minute. 126 * 127 * @return the currently selected minute, in the range (0-59) 128 * @see #setMinute(int) 129 */ getMinute()130 public int getMinute() { 131 return mDelegate.getCurrentMinute(); 132 } 133 134 /** 135 * Sets the current hour. 136 * 137 * @deprecated Use {@link #setHour(int)} 138 */ 139 @Deprecated setCurrentHour(@onNull Integer currentHour)140 public void setCurrentHour(@NonNull Integer currentHour) { 141 setHour(currentHour); 142 } 143 144 /** 145 * @return the current hour in the range (0-23) 146 * @deprecated Use {@link #getHour()} 147 */ 148 @NonNull 149 @Deprecated getCurrentHour()150 public Integer getCurrentHour() { 151 return mDelegate.getCurrentHour(); 152 } 153 154 /** 155 * Set the current minute (0-59). 156 * 157 * @deprecated Use {@link #setMinute(int)} 158 */ 159 @Deprecated setCurrentMinute(@onNull Integer currentMinute)160 public void setCurrentMinute(@NonNull Integer currentMinute) { 161 mDelegate.setCurrentMinute(currentMinute); 162 } 163 164 /** 165 * @return the current minute 166 * @deprecated Use {@link #getMinute()} 167 */ 168 @NonNull 169 @Deprecated getCurrentMinute()170 public Integer getCurrentMinute() { 171 return mDelegate.getCurrentMinute(); 172 } 173 174 /** 175 * Sets whether this widget displays time in 24-hour mode or 12-hour mode 176 * with an AM/PM picker. 177 * 178 * @param is24HourView {@code true} to display in 24-hour mode, 179 * {@code false} for 12-hour mode with AM/PM 180 * @see #is24HourView() 181 */ setIs24HourView(@onNull Boolean is24HourView)182 public void setIs24HourView(@NonNull Boolean is24HourView) { 183 if (is24HourView == null) { 184 return; 185 } 186 187 mDelegate.setIs24HourView(is24HourView); 188 } 189 190 /** 191 * @return {@code true} if this widget displays time in 24-hour mode, 192 * {@code false} otherwise} 193 * @see #setIs24HourView(Boolean) 194 */ is24HourView()195 public boolean is24HourView() { 196 return mDelegate.is24HourView(); 197 } 198 199 /** 200 * Set the callback that indicates the time has been adjusted by the user. 201 * 202 * @param onTimeChangedListener the callback, should not be null. 203 */ setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener)204 public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) { 205 mDelegate.setOnTimeChangedListener(onTimeChangedListener); 206 } 207 208 /** 209 * Sets the callback that indicates the current time is valid. 210 * 211 * @param callback the callback, may be null 212 * @hide 213 */ setValidationCallback(@ullable ValidationCallback callback)214 public void setValidationCallback(@Nullable ValidationCallback callback) { 215 mDelegate.setValidationCallback(callback); 216 } 217 218 @Override setEnabled(boolean enabled)219 public void setEnabled(boolean enabled) { 220 super.setEnabled(enabled); 221 mDelegate.setEnabled(enabled); 222 } 223 224 @Override isEnabled()225 public boolean isEnabled() { 226 return mDelegate.isEnabled(); 227 } 228 229 @Override getBaseline()230 public int getBaseline() { 231 return mDelegate.getBaseline(); 232 } 233 234 @Override onConfigurationChanged(Configuration newConfig)235 protected void onConfigurationChanged(Configuration newConfig) { 236 super.onConfigurationChanged(newConfig); 237 mDelegate.onConfigurationChanged(newConfig); 238 } 239 240 @Override onSaveInstanceState()241 protected Parcelable onSaveInstanceState() { 242 Parcelable superState = super.onSaveInstanceState(); 243 return mDelegate.onSaveInstanceState(superState); 244 } 245 246 @Override onRestoreInstanceState(Parcelable state)247 protected void onRestoreInstanceState(Parcelable state) { 248 BaseSavedState ss = (BaseSavedState) state; 249 super.onRestoreInstanceState(ss.getSuperState()); 250 mDelegate.onRestoreInstanceState(ss); 251 } 252 253 @Override getAccessibilityClassName()254 public CharSequence getAccessibilityClassName() { 255 return TimePicker.class.getName(); 256 } 257 258 /** @hide */ 259 @Override dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event)260 public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) { 261 return mDelegate.dispatchPopulateAccessibilityEvent(event); 262 } 263 264 /** 265 * A delegate interface that defined the public API of the TimePicker. Allows different 266 * TimePicker implementations. This would need to be implemented by the TimePicker delegates 267 * for the real behavior. 268 */ 269 interface TimePickerDelegate { setCurrentHour(int currentHour)270 void setCurrentHour(int currentHour); getCurrentHour()271 int getCurrentHour(); 272 setCurrentMinute(int currentMinute)273 void setCurrentMinute(int currentMinute); getCurrentMinute()274 int getCurrentMinute(); 275 setIs24HourView(boolean is24HourView)276 void setIs24HourView(boolean is24HourView); is24HourView()277 boolean is24HourView(); 278 setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener)279 void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener); setValidationCallback(ValidationCallback callback)280 void setValidationCallback(ValidationCallback callback); 281 setEnabled(boolean enabled)282 void setEnabled(boolean enabled); isEnabled()283 boolean isEnabled(); 284 getBaseline()285 int getBaseline(); 286 onConfigurationChanged(Configuration newConfig)287 void onConfigurationChanged(Configuration newConfig); 288 onSaveInstanceState(Parcelable superState)289 Parcelable onSaveInstanceState(Parcelable superState); onRestoreInstanceState(Parcelable state)290 void onRestoreInstanceState(Parcelable state); 291 dispatchPopulateAccessibilityEvent(AccessibilityEvent event)292 boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event); onPopulateAccessibilityEvent(AccessibilityEvent event)293 void onPopulateAccessibilityEvent(AccessibilityEvent event); 294 } 295 296 /** 297 * A callback interface for updating input validity when the TimePicker 298 * when included into a Dialog. 299 * 300 * @hide 301 */ 302 public static interface ValidationCallback { onValidationChanged(boolean valid)303 void onValidationChanged(boolean valid); 304 } 305 306 /** 307 * An abstract class which can be used as a start for TimePicker implementations 308 */ 309 abstract static class AbstractTimePickerDelegate implements TimePickerDelegate { 310 // The delegator 311 protected TimePicker mDelegator; 312 313 // The context 314 protected Context mContext; 315 316 // The current locale 317 protected Locale mCurrentLocale; 318 319 // Callbacks 320 protected OnTimeChangedListener mOnTimeChangedListener; 321 protected ValidationCallback mValidationCallback; 322 AbstractTimePickerDelegate(TimePicker delegator, Context context)323 public AbstractTimePickerDelegate(TimePicker delegator, Context context) { 324 mDelegator = delegator; 325 mContext = context; 326 327 // initialization based on locale 328 setCurrentLocale(Locale.getDefault()); 329 } 330 setCurrentLocale(Locale locale)331 public void setCurrentLocale(Locale locale) { 332 if (locale.equals(mCurrentLocale)) { 333 return; 334 } 335 mCurrentLocale = locale; 336 } 337 338 @Override setValidationCallback(ValidationCallback callback)339 public void setValidationCallback(ValidationCallback callback) { 340 mValidationCallback = callback; 341 } 342 onValidationChanged(boolean valid)343 protected void onValidationChanged(boolean valid) { 344 if (mValidationCallback != null) { 345 mValidationCallback.onValidationChanged(valid); 346 } 347 } 348 } 349 } 350