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