/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import android.annotation.Widget; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.NumberPicker; import com.android.internal.R; import java.text.DateFormatSymbols; import java.util.Calendar; /** * A view for selecting the time of day, in either 24 hour or AM/PM mode. * * The hour, each minute digit, and AM/PM (if applicable) can be conrolled by * vertical spinners. * * The hour can be entered by keyboard input. Entering in two digit hours * can be accomplished by hitting two digits within a timeout of about a * second (e.g. '1' then '2' to select 12). * * The minutes can be entered by entering single digits. * * Under AM/PM mode, the user can hit 'a', 'A", 'p' or 'P' to pick. * * For a dialog using this view, see {@link android.app.TimePickerDialog}. * *
See the Time Picker * tutorial.
*/ @Widget public class TimePicker extends FrameLayout { /** * A no-op callback used in the constructor to avoid null checks * later in the code. */ private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() { public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { } }; // state private int mCurrentHour = 0; // 0-23 private int mCurrentMinute = 0; // 0-59 private Boolean mIs24HourView = false; private boolean mIsAm; // ui components private final NumberPicker mHourPicker; private final NumberPicker mMinutePicker; private final Button mAmPmButton; private final String mAmText; private final String mPmText; // callbacks private OnTimeChangedListener mOnTimeChangedListener; /** * The callback interface used to indicate the time has been adjusted. */ public interface OnTimeChangedListener { /** * @param view The view associated with this listener. * @param hourOfDay The current hour. * @param minute The current minute. */ void onTimeChanged(TimePicker view, int hourOfDay, int minute); } public TimePicker(Context context) { this(context, null); } public TimePicker(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TimePicker(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.time_picker, this, // we are the parent true); // hour mHourPicker = (NumberPicker) findViewById(R.id.hour); mHourPicker.setOnChangeListener(new NumberPicker.OnChangedListener() { public void onChanged(NumberPicker spinner, int oldVal, int newVal) { mCurrentHour = newVal; if (!mIs24HourView) { // adjust from [1-12] to [0-11] internally, with the times // written "12:xx" being the start of the half-day if (mCurrentHour == 12) { mCurrentHour = 0; } if (!mIsAm) { // PM means 12 hours later than nominal mCurrentHour += 12; } } onTimeChanged(); } }); // digits of minute mMinutePicker = (NumberPicker) findViewById(R.id.minute); mMinutePicker.setRange(0, 59); mMinutePicker.setSpeed(100); mMinutePicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); mMinutePicker.setOnChangeListener(new NumberPicker.OnChangedListener() { public void onChanged(NumberPicker spinner, int oldVal, int newVal) { mCurrentMinute = newVal; onTimeChanged(); } }); // am/pm mAmPmButton = (Button) findViewById(R.id.amPm); // now that the hour/minute picker objects have been initialized, set // the hour range properly based on the 12/24 hour display mode. configurePickerRanges(); // initialize to current time Calendar cal = Calendar.getInstance(); setOnTimeChangedListener(NO_OP_CHANGE_LISTENER); // by default we're not in 24 hour mode setCurrentHour(cal.get(Calendar.HOUR_OF_DAY)); setCurrentMinute(cal.get(Calendar.MINUTE)); mIsAm = (mCurrentHour < 12); /* Get the localized am/pm strings and use them in the spinner */ DateFormatSymbols dfs = new DateFormatSymbols(); String[] dfsAmPm = dfs.getAmPmStrings(); mAmText = dfsAmPm[Calendar.AM]; mPmText = dfsAmPm[Calendar.PM]; mAmPmButton.setText(mIsAm ? mAmText : mPmText); mAmPmButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { requestFocus(); if (mIsAm) { // Currently AM switching to PM if (mCurrentHour < 12) { mCurrentHour += 12; } } else { // Currently PM switching to AM if (mCurrentHour >= 12) { mCurrentHour -= 12; } } mIsAm = !mIsAm; mAmPmButton.setText(mIsAm ? mAmText : mPmText); onTimeChanged(); } }); if (!isEnabled()) { setEnabled(false); } } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); mMinutePicker.setEnabled(enabled); mHourPicker.setEnabled(enabled); mAmPmButton.setEnabled(enabled); } /** * Used to save / restore state of time picker */ private static class SavedState extends BaseSavedState { private final int mHour; private final int mMinute; private SavedState(Parcelable superState, int hour, int minute) { super(superState); mHour = hour; mMinute = minute; } private SavedState(Parcel in) { super(in); mHour = in.readInt(); mMinute = in.readInt(); } public int getHour() { return mHour; } public int getMinute() { return mMinute; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mHour); dest.writeInt(mMinute); } public static final Parcelable.Creator