Home | History | Annotate | Download | only in widget
      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          */
     64         void onTimeChanged(TimePicker view, int hourOfDay, int minute);
     65     }
     66 
     67     public TimePicker(Context context) {
     68         this(context, null);
     69     }
     70 
     71     public TimePicker(Context context, AttributeSet attrs) {
     72         this(context, attrs, R.attr.timePickerStyle);
     73     }
     74 
     75     public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
     76         this(context, attrs, defStyleAttr, 0);
     77     }
     78 
     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 TimePickerSpinnerDelegate(
     90                         this, context, attrs, defStyleAttr, defStyleRes);
     91                 break;
     92             case MODE_SPINNER:
     93             default:
     94                 mDelegate = new TimePickerClockDelegate(
     95                         this, context, attrs, defStyleAttr, defStyleRes);
     96                 break;
     97         }
     98     }
     99 
    100     /**
    101      * Set the current hour.
    102      */
    103     public void setCurrentHour(Integer currentHour) {
    104         mDelegate.setCurrentHour(currentHour);
    105     }
    106 
    107     /**
    108      * @return The current hour in the range (0-23).
    109      */
    110     public Integer getCurrentHour() {
    111         return mDelegate.getCurrentHour();
    112     }
    113 
    114     /**
    115      * Set the current minute (0-59).
    116      */
    117     public void setCurrentMinute(Integer currentMinute) {
    118         mDelegate.setCurrentMinute(currentMinute);
    119     }
    120 
    121     /**
    122      * @return The current minute.
    123      */
    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      */
    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      */
    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      */
    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      */
    159     public void setValidationCallback(@Nullable ValidationCallback callback) {
    160         mDelegate.setValidationCallback(callback);
    161     }
    162 
    163     @Override
    164     public void setEnabled(boolean enabled) {
    165         super.setEnabled(enabled);
    166         mDelegate.setEnabled(enabled);
    167     }
    168 
    169     @Override
    170     public boolean isEnabled() {
    171         return mDelegate.isEnabled();
    172     }
    173 
    174     @Override
    175     public int getBaseline() {
    176         return mDelegate.getBaseline();
    177     }
    178 
    179     @Override
    180     protected void onConfigurationChanged(Configuration newConfig) {
    181         super.onConfigurationChanged(newConfig);
    182         mDelegate.onConfigurationChanged(newConfig);
    183     }
    184 
    185     @Override
    186     protected Parcelable onSaveInstanceState() {
    187         Parcelable superState = super.onSaveInstanceState();
    188         return mDelegate.onSaveInstanceState(superState);
    189     }
    190 
    191     @Override
    192     protected void onRestoreInstanceState(Parcelable state) {
    193         BaseSavedState ss = (BaseSavedState) state;
    194         super.onRestoreInstanceState(ss.getSuperState());
    195         mDelegate.onRestoreInstanceState(ss);
    196     }
    197 
    198     @Override
    199     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
    200         return mDelegate.dispatchPopulateAccessibilityEvent(event);
    201     }
    202 
    203     @Override
    204     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
    205         super.onPopulateAccessibilityEvent(event);
    206         mDelegate.onPopulateAccessibilityEvent(event);
    207     }
    208 
    209     @Override
    210     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    211         super.onInitializeAccessibilityEvent(event);
    212         mDelegate.onInitializeAccessibilityEvent(event);
    213     }
    214 
    215     @Override
    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 {
    227         void setCurrentHour(Integer currentHour);
    228         Integer getCurrentHour();
    229 
    230         void setCurrentMinute(Integer currentMinute);
    231         Integer getCurrentMinute();
    232 
    233         void setIs24HourView(Boolean is24HourView);
    234         boolean is24HourView();
    235 
    236         void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
    237         void setValidationCallback(ValidationCallback callback);
    238 
    239         void setEnabled(boolean enabled);
    240         boolean isEnabled();
    241 
    242         int getBaseline();
    243 
    244         void onConfigurationChanged(Configuration newConfig);
    245 
    246         Parcelable onSaveInstanceState(Parcelable superState);
    247         void onRestoreInstanceState(Parcelable state);
    248 
    249         boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
    250         void onPopulateAccessibilityEvent(AccessibilityEvent event);
    251         void onInitializeAccessibilityEvent(AccessibilityEvent event);
    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 {
    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 
    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 
    290         public void setCurrentLocale(Locale locale) {
    291             if (locale.equals(mCurrentLocale)) {
    292                 return;
    293             }
    294             mCurrentLocale = locale;
    295         }
    296 
    297         @Override
    298         public void setValidationCallback(ValidationCallback callback) {
    299             mValidationCallback = callback;
    300         }
    301 
    302         protected void onValidationChanged(boolean valid) {
    303             if (mValidationCallback != null) {
    304                 mValidationCallback.onValidationChanged(valid);
    305             }
    306         }
    307     }
    308 }
    309