TimePickerSpinnerDelegate.java revision 3053b2fdcf7486f2e2f572f9b05ce65dacdd2b4c
1eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio/* 2eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Copyright (C) 2013 The Android Open Source Project 3eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 4eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License"); 5eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * you may not use this file except in compliance with the License. 6eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * You may obtain a copy of the License at 7eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 8eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * http://www.apache.org/licenses/LICENSE-2.0 9eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 10eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Unless required by applicable law or agreed to in writing, software 11eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS, 12eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * See the License for the specific language governing permissions and 14eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * limitations under the License. 15eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 16eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 17eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Megliopackage android.widget; 18eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 19eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.animation.Keyframe; 20eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.animation.ObjectAnimator; 21eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.animation.PropertyValuesHolder; 22eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.content.Context; 2360727e07c6ef72e2f494266939c02494a3df28f8Alan Viveretteimport android.content.res.ColorStateList; 24eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.content.res.Configuration; 25eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.content.res.Resources; 26eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.content.res.TypedArray; 275134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viveretteimport android.graphics.Color; 28eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.os.Parcel; 29eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.os.Parcelable; 30eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.text.TextUtils; 31eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.text.format.DateFormat; 32014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglioimport android.text.format.DateUtils; 33eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.util.AttributeSet; 34eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.util.Log; 35eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.HapticFeedbackConstants; 36eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.KeyCharacterMap; 37eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.KeyEvent; 38eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.LayoutInflater; 39eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.View; 40eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.ViewGroup; 41eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.accessibility.AccessibilityEvent; 42eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport android.view.accessibility.AccessibilityNodeInfo; 43eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 44eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport com.android.internal.R; 45eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 46eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport java.text.DateFormatSymbols; 47eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport java.util.ArrayList; 48eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglioimport java.util.Calendar; 49014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglioimport java.util.Locale; 50eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 51eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio/** 52eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * A view for selecting the time of day, in either 24 hour or AM/PM mode. 53eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 543053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haaseclass TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate implements 55eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio RadialTimePickerView.OnValueSelectedListener { 56eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 57eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final String TAG = "TimePickerDelegate"; 58eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 59eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Index used by RadialPickerLayout 60eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int HOUR_INDEX = 0; 61eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int MINUTE_INDEX = 1; 62eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 63eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // NOT a real index for the purpose of what's showing. 64eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int AMPM_INDEX = 2; 65eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 66eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Also NOT a real index, just used for keyboard mode. 67eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int ENABLE_PICKER_INDEX = 3; 68eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 69eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int AM = 0; 70eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int PM = 1; 71eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 72eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final boolean DEFAULT_ENABLED_STATE = true; 73eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean mIsEnabled = DEFAULT_ENABLED_STATE; 74eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 75eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int HOURS_IN_HALF_DAY = 12; 76eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 77eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Delay in ms before starting the pulse animation 78eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int PULSE_ANIMATOR_DELAY = 300; 79eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 80eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Duration in ms of the pulse animation 81eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static final int PULSE_ANIMATOR_DURATION = 544; 82eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 83eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private TextView mHourView; 84eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private TextView mMinuteView; 85eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private TextView mAmPmTextView; 86eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private RadialTimePickerView mRadialTimePickerView; 87eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private TextView mSeparatorView; 88eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 89eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private ViewGroup mLayoutButtons; 90eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 91eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mAmText; 92eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mPmText; 93eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 94eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean mAllowAutoAdvance; 95eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int mInitialHourOfDay; 96eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int mInitialMinute; 97eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean mIs24HourView; 98eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 99eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // For hardware IME input. 100eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private char mPlaceholderText; 101eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mDoublePlaceholderText; 102eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mDeletedKeyFormat; 103eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean mInKbMode; 104eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private ArrayList<Integer> mTypedTimes = new ArrayList<Integer>(); 105eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private Node mLegalTimesTree; 106eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int mAmKeyCode; 107eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int mPmKeyCode; 108eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 109eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // For showing the done button when in a Dialog 110eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private Button mDoneButton; 111eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean mShowDoneButton; 112eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private TimePicker.TimePickerDismissCallback mDismissCallback; 113eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 114eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Accessibility strings. 115eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mHourPickerDescription; 116eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mSelectHours; 117eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mMinutePickerDescription; 118eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private String mSelectMinutes; 119eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 120014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio private Calendar mTempCalendar; 121014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio 1223053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase public TimePickerSpinnerDelegate(TimePicker delegator, Context context, AttributeSet attrs, 1233053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase int defStyleAttr, int defStyleRes) { 124eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio super(delegator, context); 125eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 126eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // process style attributes 127eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final TypedArray a = mContext.obtainStyledAttributes(attrs, 128eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio R.styleable.TimePicker, defStyleAttr, defStyleRes); 12960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( 13060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette Context.LAYOUT_INFLATER_SERVICE); 131eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final Resources res = mContext.getResources(); 132eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 133eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourPickerDescription = res.getString(R.string.hour_picker_description); 134eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mSelectHours = res.getString(R.string.select_hours); 135eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinutePickerDescription = res.getString(R.string.minute_picker_description); 136eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mSelectMinutes = res.getString(R.string.select_minutes); 137eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 13860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout, 13960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.layout.time_picker_holo); 14060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final View mainView = inflater.inflate(layoutResourceId, null); 14160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mDelegator.addView(mainView); 142eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 14360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mHourView = (TextView) mainView.findViewById(R.id.hours); 14460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mSeparatorView = (TextView) mainView.findViewById(R.id.separator); 14560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mMinuteView = (TextView) mainView.findViewById(R.id.minutes); 14660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mAmPmTextView = (TextView) mainView.findViewById(R.id.ampm_label); 14760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mLayoutButtons = (ViewGroup) mainView.findViewById(R.id.layout_buttons); 1485134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette 1495134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette // Set up text appearances from style. 15060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final int headerTimeTextAppearance = a.getResourceId( 15160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.styleable.TimePicker_headerTimeTextAppearance, 0); 1525134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette if (headerTimeTextAppearance != 0) { 1535134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette mHourView.setTextAppearance(context, headerTimeTextAppearance); 1545134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette mSeparatorView.setTextAppearance(context, headerTimeTextAppearance); 1555134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette mMinuteView.setTextAppearance(context, headerTimeTextAppearance); 1565134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette } 1575134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette 15860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final int headerSelectedTextColor = a.getColor( 15960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.styleable.TimePicker_headerSelectedTextColor, 16060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette res.getColor(R.color.timepicker_default_selector_color_material)); 16160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mHourView.setTextColor(ColorStateList.addFirstIfMissing(mHourView.getTextColors(), 16260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.attr.state_selected, headerSelectedTextColor)); 16360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mMinuteView.setTextColor(ColorStateList.addFirstIfMissing(mMinuteView.getTextColors(), 16460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.attr.state_selected, headerSelectedTextColor)); 16560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette 16660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final int headerAmPmTextAppearance = a.getResourceId( 16760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.styleable.TimePicker_headerAmPmTextAppearance, 0); 1685134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette if (headerAmPmTextAppearance != 0) { 1695134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette mAmPmTextView.setTextAppearance(context, headerAmPmTextAppearance); 1705134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette } 1715134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette 17260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final int headerBackgroundColor = a.getColor( 17360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.styleable.TimePicker_headerBackgroundColor, Color.TRANSPARENT); 1745134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette if (headerBackgroundColor != Color.TRANSPARENT) { 1755134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette mLayoutButtons.setBackgroundColor(headerBackgroundColor); 17660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mainView.findViewById(R.id.time_header).setBackgroundColor(headerBackgroundColor); 1775134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette } 1785134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette 17960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette a.recycle(); 1805134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette 18160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mRadialTimePickerView = (RadialTimePickerView) mainView.findViewById( 18260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette R.id.radial_picker); 18360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mDoneButton = (Button) mainView.findViewById(R.id.done_button); 184eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 185eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String[] amPmTexts = new DateFormatSymbols().getAmPmStrings(); 186eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmText = amPmTexts[0]; 187eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mPmText = amPmTexts[1]; 188eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 189eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setupListeners(); 190eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 191eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAllowAutoAdvance = true; 192eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 193eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Set up for keyboard mode. 194eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoublePlaceholderText = res.getString(R.string.time_placeholder); 195eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDeletedKeyFormat = res.getString(R.string.deleted_key); 196eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mPlaceholderText = mDoublePlaceholderText.charAt(0); 197eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmKeyCode = mPmKeyCode = -1; 198eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio generateLegalTimesTree(); 199eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 200eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Initialize with current time 201eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final Calendar calendar = Calendar.getInstance(mCurrentLocale); 202eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); 203eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int currentMinute = calendar.get(Calendar.MINUTE); 204eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX, false); 205eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 206eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 207eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void initialize(int hourOfDay, int minute, boolean is24HourView, int index, 208eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio boolean showDoneButton) { 209eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInitialHourOfDay = hourOfDay; 210eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInitialMinute = minute; 211eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mIs24HourView = is24HourView; 212eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInKbMode = false; 213eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mShowDoneButton = showDoneButton; 214eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateUI(index); 215eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 216eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 217eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void setupListeners() { 218eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio KeyboardListener keyboardListener = new KeyboardListener(); 219eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.setOnKeyListener(keyboardListener); 220eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 221eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourView.setOnKeyListener(keyboardListener); 222eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinuteView.setOnKeyListener(keyboardListener); 223eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setOnKeyListener(keyboardListener); 224eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setOnValueSelectedListener(this); 225eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setOnKeyListener(keyboardListener); 226eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 227eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourView.setOnClickListener(new View.OnClickListener() { 228eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 229eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onClick(View v) { 230eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setCurrentItemShowing(HOUR_INDEX, true, false, true); 231eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tryVibrate(); 232eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 233eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio }); 234eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinuteView.setOnClickListener(new View.OnClickListener() { 235eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 236eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onClick(View v) { 237eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setCurrentItemShowing(MINUTE_INDEX, true, false, true); 238eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tryVibrate(); 239eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 240eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio }); 241eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoneButton.setOnClickListener(new View.OnClickListener() { 242eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 243eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onClick(View v) { 244eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mInKbMode && isTypedTimeFullyLegal()) { 245eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio finishKbMode(false); 246eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 247eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tryVibrate(); 248eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 249eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mDismissCallback != null) { 250eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), 251eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio getCurrentMinute()); 252eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 253eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 254eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio }); 255eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoneButton.setOnKeyListener(keyboardListener); 256eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 257eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 258eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateUI(int index) { 259eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Update RadialPicker values 260eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateRadialPicker(index); 261eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Enable or disable the AM/PM view. 262eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderAmPm(); 263eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Show or hide Done button 264eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateDoneButton(); 265eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Update Hour and Minutes 266eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderHour(mInitialHourOfDay, true); 267eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Update time separator 268eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderSeparator(); 269eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Update Minutes 270eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderMinute(mInitialMinute); 271eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Invalidate everything 272eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.invalidate(); 273eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 274eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 275eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateRadialPicker(int index) { 276eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24HourView); 277eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setCurrentItemShowing(index, false, true, true); 278eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 279eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 280eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int computeMaxWidthOfNumbers(int max) { 281eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio TextView tempView = new TextView(mContext); 2825134478151d8aa3d776f8d4f368dbcdbc501a92aAlan Viverette tempView.setTextAppearance(mContext, R.style.TextAppearance_Material_TimePicker_TimeLabel); 283eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 284eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio ViewGroup.LayoutParams.WRAP_CONTENT); 285eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tempView.setLayoutParams(lp); 286eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int maxWidth = 0; 287eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int minutes = 0; minutes < max; minutes++) { 288eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final String text = String.format("%02d", minutes); 289eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tempView.setText(text); 290eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tempView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 291eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio maxWidth = Math.max(maxWidth, tempView.getMeasuredWidth()); 292eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 293eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return maxWidth; 294eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 295eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 296eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateHeaderAmPm() { 297eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mIs24HourView) { 298eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setVisibility(View.GONE); 299eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 300eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setVisibility(View.VISIBLE); 301eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, 302eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio "hm"); 303eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 304eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio boolean amPmOnLeft = bestDateTimePattern.startsWith("a"); 305eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (TextUtils.getLayoutDirectionFromLocale(mCurrentLocale) == 306eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio View.LAYOUT_DIRECTION_RTL) { 307eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio amPmOnLeft = !amPmOnLeft; 308eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 309eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 310eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) 311eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.getLayoutParams(); 312eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 313eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (amPmOnLeft) { 314eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio layoutParams.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */); 315eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio layoutParams.removeRule(RelativeLayout.RIGHT_OF); 316eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.separator); 317eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 318eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio layoutParams.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */); 319eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio layoutParams.removeRule(RelativeLayout.LEFT_OF); 320eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio layoutParams.addRule(RelativeLayout.RIGHT_OF, R.id.separator); 321eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 322eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 323eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateAmPmDisplay(mInitialHourOfDay < 12 ? AM : PM); 324eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setOnClickListener(new View.OnClickListener() { 325eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 326eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onClick(View v) { 327eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tryVibrate(); 328eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int amOrPm = mRadialTimePickerView.getAmOrPm(); 329eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (amOrPm == AM) { 330eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio amOrPm = PM; 331eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (amOrPm == PM){ 332eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio amOrPm = AM; 333eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 334eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateAmPmDisplay(amOrPm); 335eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setAmOrPm(amOrPm); 336eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 337eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio }); 338eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 339eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 340eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 341eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateDoneButton() { 342eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLayoutButtons.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE); 343eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 344eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 345eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 346eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Set the current hour. 347eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 348eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 349eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setCurrentHour(Integer currentHour) { 350eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mInitialHourOfDay == currentHour) { 351eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return; 352eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 353eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInitialHourOfDay = currentHour; 354eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderHour(currentHour, true /* accessibility announce */); 355eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderAmPm(); 356eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setCurrentHour(currentHour); 357eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM); 358eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.invalidate(); 359eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio onTimeChanged(); 360eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 361eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 362eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 363eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return The current hour in the range (0-23). 364eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 365eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 366eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public Integer getCurrentHour() { 367eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int currentHour = mRadialTimePickerView.getCurrentHour(); 368eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mIs24HourView) { 369eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return currentHour; 370eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 371eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio switch(mRadialTimePickerView.getAmOrPm()) { 372eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case PM: 373eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY; 374eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case AM: 375eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio default: 376eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return currentHour % HOURS_IN_HALF_DAY; 377eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 378eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 379eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 380eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 381eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 382eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Set the current minute (0-59). 383eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 384eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 385eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setCurrentMinute(Integer currentMinute) { 386eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mInitialMinute == currentMinute) { 387eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return; 388eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 389eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInitialMinute = currentMinute; 390eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderMinute(currentMinute); 391eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setCurrentMinute(currentMinute); 392eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.invalidate(); 393eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio onTimeChanged(); 394eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 395eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 396eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 397eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return The current minute. 398eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 399eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 400eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public Integer getCurrentMinute() { 401eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mRadialTimePickerView.getCurrentMinute(); 402eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 403eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 404eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 405eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Set whether in 24 hour or AM/PM mode. 406eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 407eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param is24HourView True = 24 hour mode. False = AM/PM. 408eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 409eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 410eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setIs24HourView(Boolean is24HourView) { 411eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (is24HourView == mIs24HourView) { 412eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return; 413eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 414eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mIs24HourView = is24HourView; 415eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio generateLegalTimesTree(); 416eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int hour = mRadialTimePickerView.getCurrentHour(); 417eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInitialHourOfDay = hour; 418eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderHour(hour, false /* no accessibility announce */); 419eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderAmPm(); 420eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateRadialPicker(mRadialTimePickerView.getCurrentItemShowing()); 421eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.invalidate(); 422eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 423eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 424eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 425eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return true if this is in 24 hour view else false. 426eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 427eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 428eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean is24HourView() { 429eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mIs24HourView; 430eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 431eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 432eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 433eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener callback) { 434eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mOnTimeChangedListener = callback; 435eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 436eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 437eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 438eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setEnabled(boolean enabled) { 439eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourView.setEnabled(enabled); 440eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinuteView.setEnabled(enabled); 441eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setEnabled(enabled); 442eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setEnabled(enabled); 443eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mIsEnabled = enabled; 444eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 445eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 446eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 447eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean isEnabled() { 448eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mIsEnabled; 449eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 450eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 451eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 452eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setShowDoneButton(boolean showDoneButton) { 453eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mShowDoneButton = showDoneButton; 454eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateDoneButton(); 455eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 456eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 457eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 458eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) { 459eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDismissCallback = callback; 460eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 461eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 462eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 463eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public int getBaseline() { 464eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // does not support baseline alignment 465eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return -1; 466eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 467eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 468eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 469eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onConfigurationChanged(Configuration newConfig) { 470eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateUI(mRadialTimePickerView.getCurrentItemShowing()); 471eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 472eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 473eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 474eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public Parcelable onSaveInstanceState(Parcelable superState) { 475eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return new SavedState(superState, getCurrentHour(), getCurrentMinute(), 476eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing(), 477eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio isShowDoneButton()); 478eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 479eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 480eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 481eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onRestoreInstanceState(Parcelable state) { 482eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio SavedState ss = (SavedState) state; 483eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setInKbMode(ss.inKbMode()); 484eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setTypedTimes(ss.getTypesTimes()); 485eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing(), 486eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio ss.isShowDoneButton()); 487eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.invalidate(); 488eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mInKbMode) { 489eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tryStartingKbMode(-1); 490eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourView.invalidate(); 491eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 492eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 493eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 494eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 495014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio public void setCurrentLocale(Locale locale) { 496014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio super.setCurrentLocale(locale); 497014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio mTempCalendar = Calendar.getInstance(locale); 498014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio } 499014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio 500014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio @Override 501eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 502014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio onPopulateAccessibilityEvent(event); 503014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio return true; 504eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 505eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 506eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 507eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 508014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio int flags = DateUtils.FORMAT_SHOW_TIME; 509014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio if (mIs24HourView) { 510014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio flags |= DateUtils.FORMAT_24HOUR; 511014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio } else { 512014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio flags |= DateUtils.FORMAT_12HOUR; 513014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio } 514014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour()); 515014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio mTempCalendar.set(Calendar.MINUTE, getCurrentMinute()); 516014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio String selectedDate = DateUtils.formatDateTime(mContext, 517014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio mTempCalendar.getTimeInMillis(), flags); 518014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio event.getText().add(selectedDate); 519eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 520eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 521eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 522eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 523014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio event.setClassName(TimePicker.class.getName()); 524eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 525eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 526eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 527eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 528014b8cfcf87507e629a728582b196b62aee71e37Fabrice Di Meglio info.setClassName(TimePicker.class.getName()); 529eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 530eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 531eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 532eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Set whether in keyboard mode or not. 533eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 534eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param inKbMode True means in keyboard mode. 535eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 536eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void setInKbMode(boolean inKbMode) { 537eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInKbMode = inKbMode; 538eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 539eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 540eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 541eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return true if in keyboard mode 542eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 543eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean inKbMode() { 544eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mInKbMode; 545eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 546eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 547eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void setTypedTimes(ArrayList<Integer> typeTimes) { 548eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes = typeTimes; 549eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 550eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 551eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 552eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return an array of typed times 553eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 554eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private ArrayList<Integer> getTypedTimes() { 555eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mTypedTimes; 556eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 557eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 558eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 559eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return the index of the current item showing 560eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 561eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int getCurrentItemShowing() { 562eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mRadialTimePickerView.getCurrentItemShowing(); 563eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 564eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 565abdd154334eced2595d42e17a9dbac242a9af7daCraig Stout @Override 566abdd154334eced2595d42e17a9dbac242a9af7daCraig Stout public boolean isShowDoneButton() { 567eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mShowDoneButton; 568eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 569eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 570eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 571eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Propagate the time change 572eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 573eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void onTimeChanged() { 574eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); 575eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mOnTimeChangedListener != null) { 576eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mOnTimeChangedListener.onTimeChanged(mDelegator, 577eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio getCurrentHour(), getCurrentMinute()); 578eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 579eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 580eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 581eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 582eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Used to save / restore state of time picker 583eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 584eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static class SavedState extends View.BaseSavedState { 585eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 586eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final int mHour; 587eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final int mMinute; 588eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final boolean mIs24HourMode; 589eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final boolean mInKbMode; 590eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final ArrayList<Integer> mTypedTimes; 591eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final int mCurrentItemShowing; 592eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private final boolean mShowDoneButton; 593eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 594eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode, 595eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio boolean isKbMode, ArrayList<Integer> typedTimes, 596eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int currentItemShowing, boolean showDoneButton) { 597eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio super(superState); 598eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHour = hour; 599eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinute = minute; 600eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mIs24HourMode = is24HourMode; 601eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInKbMode = isKbMode; 602eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes = typedTimes; 603eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mCurrentItemShowing = currentItemShowing; 604eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mShowDoneButton = showDoneButton; 605eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 606eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 607eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private SavedState(Parcel in) { 608eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio super(in); 609eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHour = in.readInt(); 610eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinute = in.readInt(); 611eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mIs24HourMode = (in.readInt() == 1); 612eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInKbMode = (in.readInt() == 1); 613eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes = in.readArrayList(getClass().getClassLoader()); 614eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mCurrentItemShowing = in.readInt(); 615eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mShowDoneButton = (in.readInt() == 1); 616eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 617eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 618eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public int getHour() { 619eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mHour; 620eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 621eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 622eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public int getMinute() { 623eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mMinute; 624eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 625eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 626eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean is24HourMode() { 627eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mIs24HourMode; 628eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 629eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 630eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean inKbMode() { 631eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mInKbMode; 632eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 633eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 634eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public ArrayList<Integer> getTypesTimes() { 635eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mTypedTimes; 636eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 637eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 638eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public int getCurrentItemShowing() { 639eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mCurrentItemShowing; 640eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 641eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 642eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean isShowDoneButton() { 643eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mShowDoneButton; 644eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 645eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 646eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 647eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void writeToParcel(Parcel dest, int flags) { 648eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio super.writeToParcel(dest, flags); 649eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeInt(mHour); 650eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeInt(mMinute); 651eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeInt(mIs24HourMode ? 1 : 0); 652eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeInt(mInKbMode ? 1 : 0); 653eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeList(mTypedTimes); 654eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeInt(mCurrentItemShowing); 655eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio dest.writeInt(mShowDoneButton ? 1 : 0); 656eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 657eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 658eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @SuppressWarnings({"unused", "hiding"}) 659eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { 660eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public SavedState createFromParcel(Parcel in) { 661eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return new SavedState(in); 662eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 663eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 664eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public SavedState[] newArray(int size) { 665eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return new SavedState[size]; 666eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 667eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio }; 668eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 669eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 670eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void tryVibrate() { 671eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDelegator.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); 672eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 673eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 674eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateAmPmDisplay(int amOrPm) { 675eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (amOrPm == AM) { 676eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setText(mAmText); 677eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(mAmText); 678eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (amOrPm == PM){ 679eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setText(mPmText); 680eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(mPmText); 681eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 682eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmPmTextView.setText(mDoublePlaceholderText); 683eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 684eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 685eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 686eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 687eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Called by the picker for updating the header display. 688eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 689eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 690eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) { 691eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (pickerIndex == HOUR_INDEX) { 692eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderHour(newValue, false); 693eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String announcement = String.format("%d", newValue); 694eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mAllowAutoAdvance && autoAdvance) { 695eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setCurrentItemShowing(MINUTE_INDEX, true, true, false); 696eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio announcement += ". " + mSelectMinutes; 697eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 698eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setContentDescription( 699eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourPickerDescription + ": " + newValue); 700eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 701eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 702eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(announcement); 703eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (pickerIndex == MINUTE_INDEX){ 704eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderMinute(newValue); 705eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + newValue); 706eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (pickerIndex == AMPM_INDEX) { 707eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateAmPmDisplay(newValue); 708eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (pickerIndex == ENABLE_PICKER_INDEX) { 709eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!isTypedTimeFullyLegal()) { 710eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.clear(); 711eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 712eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio finishKbMode(true); 713eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 714eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 715eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 716eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateHeaderHour(int value, boolean announce) { 717eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, 718eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio (mIs24HourView) ? "Hm" : "hm"); 719eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int lengthPattern = bestDateTimePattern.length(); 720eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio boolean hourWithTwoDigit = false; 721eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio char hourFormat = '\0'; 722eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save 723eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // the hour format that we found. 724eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int i = 0; i < lengthPattern; i++) { 725eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final char c = bestDateTimePattern.charAt(i); 726eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (c == 'H' || c == 'h' || c == 'K' || c == 'k') { 727eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio hourFormat = c; 728eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) { 729eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio hourWithTwoDigit = true; 730eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 731eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio break; 732eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 733eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 734eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final String format; 735eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (hourWithTwoDigit) { 736eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio format = "%02d"; 737eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 738eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio format = "%d"; 739eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 740eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mIs24HourView) { 741eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // 'k' means 1-24 hour 742eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (hourFormat == 'k' && value == 0) { 743eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio value = 24; 744eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 745eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 746eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // 'K' means 0-11 hour 747eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio value = modulo12(value, hourFormat == 'K'); 748eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 749eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio CharSequence text = String.format(format, value); 750eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourView.setText(text); 751eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (announce) { 752eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(text); 753eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 754eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 755eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 756eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static int modulo12(int n, boolean startWithZero) { 757eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int value = n % 12; 758eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (value == 0 && !startWithZero) { 759eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio value = 12; 760eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 761eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return value; 762eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 763eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 764eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 765eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":". 766eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 767eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * See http://unicode.org/cldr/trac/browser/trunk/common/main 768eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 769eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the 770eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * separator as the character which is just after the hour marker in the returned pattern. 771eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 772eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateHeaderSeparator() { 773eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, 774eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio (mIs24HourView) ? "Hm" : "hm"); 775eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final String separatorText; 776eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats 777eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final char[] hourFormats = {'H', 'h', 'K', 'k'}; 778eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int hIndex = lastIndexOfAny(bestDateTimePattern, hourFormats); 779eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (hIndex == -1) { 780eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Default case 781eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio separatorText = ":"; 782eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 783eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1)); 784eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 785eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mSeparatorView.setText(separatorText); 786eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 787eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 788eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio static private int lastIndexOfAny(String str, char[] any) { 789eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int lengthAny = any.length; 790eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (lengthAny > 0) { 791eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int i = str.length() - 1; i >= 0; i--) { 792eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio char c = str.charAt(i); 793eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int j = 0; j < lengthAny; j++) { 794eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (c == any[j]) { 795eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return i; 796eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 797eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 798eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 799eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 800eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return -1; 801eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 802eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 803eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateHeaderMinute(int value) { 804eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (value == 60) { 805eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio value = 0; 806eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 807eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio CharSequence text = String.format(mCurrentLocale, "%02d", value); 808eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(text); 809eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinuteView.setText(text); 810eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 811eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 812eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 813eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Show either Hours or Minutes. 814eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 815eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate, 816eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio boolean announce) { 817eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setCurrentItemShowing(index, animateCircle); 818eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 819eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio TextView labelToAnimate; 820eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (index == HOUR_INDEX) { 821eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int hours = mRadialTimePickerView.getCurrentHour(); 822eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mIs24HourView) { 823eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio hours = hours % 12; 824eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 825eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setContentDescription(mHourPickerDescription + ": " + hours); 826eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (announce) { 827eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(mSelectHours); 828eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 829eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio labelToAnimate = mHourView; 830eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 831eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int minutes = mRadialTimePickerView.getCurrentMinute(); 832eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + minutes); 833eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (announce) { 834eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(mSelectMinutes); 835eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 836eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio labelToAnimate = mMinuteView; 837eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 838eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 83960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mHourView.setSelected(index == HOUR_INDEX); 84060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mMinuteView.setSelected(index == MINUTE_INDEX); 841eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 842eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio ObjectAnimator pulseAnimator = getPulseAnimator(labelToAnimate, 0.85f, 1.1f); 843eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (delayLabelAnimate) { 844eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio pulseAnimator.setStartDelay(PULSE_ANIMATOR_DELAY); 845eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 846eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio pulseAnimator.start(); 847eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 848eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 849eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 850eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * For keyboard mode, processes key events. 851eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 852eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param keyCode the pressed key. 853eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 854eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return true if the key was successfully processed, false otherwise. 855eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 856eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean processKeyUp(int keyCode) { 857eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_BACK) { 858eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mDismissCallback != null) { 859eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDismissCallback.dismiss(mDelegator, true, getCurrentHour(), getCurrentMinute()); 860eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 861eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 862eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (keyCode == KeyEvent.KEYCODE_TAB) { 863eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if(mInKbMode) { 864eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (isTypedTimeFullyLegal()) { 865eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio finishKbMode(true); 866eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 867eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 868eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 869eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (keyCode == KeyEvent.KEYCODE_ENTER) { 870eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mInKbMode) { 871eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!isTypedTimeFullyLegal()) { 872eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 873eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 874eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio finishKbMode(false); 875eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 876eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mOnTimeChangedListener != null) { 877eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mOnTimeChangedListener.onTimeChanged(mDelegator, 878eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.getCurrentHour(), 879eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.getCurrentMinute()); 880eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 881eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mDismissCallback != null) { 882eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), getCurrentMinute()); 883eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 884eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 885eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (keyCode == KeyEvent.KEYCODE_DEL) { 886eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mInKbMode) { 887eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mTypedTimes.isEmpty()) { 888eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int deleted = deleteLastTypedKey(); 889eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String deletedKeyStr; 890eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (deleted == getAmOrPmKeyCode(AM)) { 891eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio deletedKeyStr = mAmText; 892eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (deleted == getAmOrPmKeyCode(PM)) { 893eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio deletedKeyStr = mPmText; 894eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 895eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio deletedKeyStr = String.format("%d", getValFromKeyCode(deleted)); 896eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 897eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility( 898eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String.format(mDeletedKeyFormat, deletedKeyStr)); 899eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateDisplay(true); 900eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 901eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 902eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (keyCode == KeyEvent.KEYCODE_0 || keyCode == KeyEvent.KEYCODE_1 903eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio || keyCode == KeyEvent.KEYCODE_2 || keyCode == KeyEvent.KEYCODE_3 904eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio || keyCode == KeyEvent.KEYCODE_4 || keyCode == KeyEvent.KEYCODE_5 905eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio || keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7 906eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio || keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9 907eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio || (!mIs24HourView && 908eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) { 909eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mInKbMode) { 910eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mRadialTimePickerView == null) { 911eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Something's wrong, because time picker should definitely not be null. 912eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Log.e(TAG, "Unable to initiate keyboard mode, TimePicker was null."); 913eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 914eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 915eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.clear(); 916eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio tryStartingKbMode(keyCode); 917eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 918eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 919eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We're already in keyboard mode. 920eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (addKeyIfLegal(keyCode)) { 921eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateDisplay(false); 922eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 923eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 924eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 925eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return false; 926eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 927eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 928eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 929eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Try to start keyboard mode with the specified key. 930eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 931eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param keyCode The key to use as the first press. Keyboard mode will not be started if the 932eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting 933eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * key. 934eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 935eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void tryStartingKbMode(int keyCode) { 936eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (keyCode == -1 || addKeyIfLegal(keyCode)) { 937eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInKbMode = true; 938eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoneButton.setEnabled(false); 939eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateDisplay(false); 940eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setInputEnabled(false); 941eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 942eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 943eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 944eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean addKeyIfLegal(int keyCode) { 945eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // If we're in 24hour mode, we'll need to check if the input is full. If in AM/PM mode, 946eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // we'll need to see if AM/PM have been typed. 947eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if ((mIs24HourView && mTypedTimes.size() == 4) || 948eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio (!mIs24HourView && isTypedTimeFullyLegal())) { 949eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return false; 950eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 951eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 952eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.add(keyCode); 953eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!isTypedTimeLegalSoFar()) { 954eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio deleteLastTypedKey(); 955eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return false; 956eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 957eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 958eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int val = getValFromKeyCode(keyCode); 959eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.announceForAccessibility(String.format("%d", val)); 960eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Automatically fill in 0's if AM or PM was legally entered. 961eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (isTypedTimeFullyLegal()) { 962eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mIs24HourView && mTypedTimes.size() <= 3) { 963eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); 964eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); 965eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 966eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoneButton.setEnabled(true); 967eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 968eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 969eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 970eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 971eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 972eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 973eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Traverse the tree to see if the keys that have been typed so far are legal as is, 974eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * or may become legal as more keys are typed (excluding backspace). 975eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 976eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean isTypedTimeLegalSoFar() { 977eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node node = mLegalTimesTree; 978eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int keyCode : mTypedTimes) { 979eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio node = node.canReach(keyCode); 980eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (node == null) { 981eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return false; 982eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 983eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 984eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 985eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 986eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 987eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 988eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Check if the time that has been typed so far is completely legal, as is. 989eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 990eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private boolean isTypedTimeFullyLegal() { 991eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mIs24HourView) { 992eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // For 24-hour mode, the time is legal if the hours and minutes are each legal. Note: 993eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // getEnteredTime() will ONLY call isTypedTimeFullyLegal() when NOT in 24hour mode. 994eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int[] values = getEnteredTime(null); 995eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return (values[0] >= 0 && values[1] >= 0 && values[1] < 60); 996eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 997eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // For AM/PM mode, the time is legal if it contains an AM or PM, as those can only be 998eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // legally added at specific times based on the tree's algorithm. 999eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return (mTypedTimes.contains(getAmOrPmKeyCode(AM)) || 1000eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.contains(getAmOrPmKeyCode(PM))); 1001eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1002eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1003eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1004eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int deleteLastTypedKey() { 1005eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int deleted = mTypedTimes.remove(mTypedTimes.size() - 1); 1006eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!isTypedTimeFullyLegal()) { 1007eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoneButton.setEnabled(false); 1008eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1009eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return deleted; 1010eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1011eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1012eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1013eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time. 1014eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param updateDisplays If true, update the displays with the relevant time. 1015eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1016eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void finishKbMode(boolean updateDisplays) { 1017eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mInKbMode = false; 1018eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mTypedTimes.isEmpty()) { 1019eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int values[] = getEnteredTime(null); 1020eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setCurrentHour(values[0]); 1021eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setCurrentMinute(values[1]); 1022eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mIs24HourView) { 1023eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setAmOrPm(values[2]); 1024eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1025eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mTypedTimes.clear(); 1026eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1027eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (updateDisplays) { 1028eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateDisplay(false); 1029eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mRadialTimePickerView.setInputEnabled(true); 1030eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1031eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1032eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1033eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1034eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Update the hours, minutes, and AM/PM displays with the typed times. If the typedTimes is 1035eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * empty, either show an empty display (filled with the placeholder text), or update from the 1036eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * timepicker's values. 1037eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 1038eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text. 1039eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Otherwise, revert to the timepicker's values. 1040eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1041eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void updateDisplay(boolean allowEmptyDisplay) { 1042eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!allowEmptyDisplay && mTypedTimes.isEmpty()) { 1043eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int hour = mRadialTimePickerView.getCurrentHour(); 1044eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int minute = mRadialTimePickerView.getCurrentMinute(); 1045eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderHour(hour, true); 1046eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateHeaderMinute(minute); 1047eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mIs24HourView) { 1048eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateAmPmDisplay(hour < 12 ? AM : PM); 1049eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1050eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true, true); 1051eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mDoneButton.setEnabled(true); 1052eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 1053eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio boolean[] enteredZeros = {false, false}; 1054eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int[] values = getEnteredTime(enteredZeros); 1055eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String hourFormat = enteredZeros[0] ? "%02d" : "%2d"; 1056eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d"; 1057eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String hourStr = (values[0] == -1) ? mDoublePlaceholderText : 1058eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String.format(hourFormat, values[0]).replace(' ', mPlaceholderText); 1059eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String minuteStr = (values[1] == -1) ? mDoublePlaceholderText : 1060eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText); 1061eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mHourView.setText(hourStr); 106260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mHourView.setSelected(false); 1063eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mMinuteView.setText(minuteStr); 106460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette mMinuteView.setSelected(false); 1065eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mIs24HourView) { 1066eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio updateAmPmDisplay(values[2]); 1067eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1068eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1069eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1070eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1071eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int getValFromKeyCode(int keyCode) { 1072eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio switch (keyCode) { 1073eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_0: 1074eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 0; 1075eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_1: 1076eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 1; 1077eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_2: 1078eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 2; 1079eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_3: 1080eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 3; 1081eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_4: 1082eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 4; 1083eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_5: 1084eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 5; 1085eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_6: 1086eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 6; 1087eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_7: 1088eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 7; 1089eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_8: 1090eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 8; 1091eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio case KeyEvent.KEYCODE_9: 1092eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return 9; 1093eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio default: 1094eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return -1; 1095eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1096eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1097eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1098eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1099eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Get the currently-entered time, as integer values of the hours and minutes typed. 1100eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 1101eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param enteredZeros A size-2 boolean array, which the caller should initialize, and which 1102eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * may then be used for the caller to know whether zeros had been explicitly entered as either 1103eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's. 1104eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 1105eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return A size-3 int array. The first value will be the hours, the second value will be the 1106eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * minutes, and the third will be either AM or PM. 1107eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1108eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int[] getEnteredTime(boolean[] enteredZeros) { 1109eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int amOrPm = -1; 1110eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int startIndex = 1; 1111eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (!mIs24HourView && isTypedTimeFullyLegal()) { 1112eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int keyCode = mTypedTimes.get(mTypedTimes.size() - 1); 1113eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (keyCode == getAmOrPmKeyCode(AM)) { 1114eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio amOrPm = AM; 1115eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (keyCode == getAmOrPmKeyCode(PM)){ 1116eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio amOrPm = PM; 1117eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1118eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio startIndex = 2; 1119eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1120eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int minute = -1; 1121eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int hour = -1; 1122eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int i = startIndex; i <= mTypedTimes.size(); i++) { 1123eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio int val = getValFromKeyCode(mTypedTimes.get(mTypedTimes.size() - i)); 1124eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (i == startIndex) { 1125eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio minute = val; 1126eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (i == startIndex+1) { 1127eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio minute += 10 * val; 1128eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (enteredZeros != null && val == 0) { 1129eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio enteredZeros[1] = true; 1130eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1131eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (i == startIndex+2) { 1132eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio hour = val; 1133eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (i == startIndex+3) { 1134eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio hour += 10 * val; 1135eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (enteredZeros != null && val == 0) { 1136eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio enteredZeros[0] = true; 1137eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1138eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1139eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1140eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 114160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette return new int[] { hour, minute, amOrPm }; 1142eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1143eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1144eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1145eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Get the keycode value for AM and PM in the current language. 1146eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1147eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int getAmOrPmKeyCode(int amOrPm) { 1148eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Cache the codes. 1149eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mAmKeyCode == -1 || mPmKeyCode == -1) { 1150eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Find the first character in the AM/PM text that is unique. 1151eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); 1152eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio char amChar; 1153eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio char pmChar; 1154eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int i = 0; i < Math.max(mAmText.length(), mPmText.length()); i++) { 1155eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio amChar = mAmText.toLowerCase(mCurrentLocale).charAt(i); 1156eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio pmChar = mPmText.toLowerCase(mCurrentLocale).charAt(i); 1157eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (amChar != pmChar) { 1158eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio KeyEvent[] events = kcm.getEvents(new char[]{amChar, pmChar}); 1159eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // There should be 4 events: a down and up for both AM and PM. 1160eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (events != null && events.length == 4) { 1161eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mAmKeyCode = events[0].getKeyCode(); 1162eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mPmKeyCode = events[2].getKeyCode(); 1163eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 1164eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Log.e(TAG, "Unable to find keycodes for AM and PM."); 1165eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1166eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio break; 1167eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1168eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1169eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1170eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (amOrPm == AM) { 1171eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mAmKeyCode; 1172eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else if (amOrPm == PM) { 1173eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return mPmKeyCode; 1174eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1175eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1176eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return -1; 1177eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1178eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1179eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1180eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Create a tree for deciding what keys can legally be typed. 1181eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1182eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private void generateLegalTimesTree() { 1183eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Create a quick cache of numbers to their keycodes. 1184eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k0 = KeyEvent.KEYCODE_0; 1185eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k1 = KeyEvent.KEYCODE_1; 1186eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k2 = KeyEvent.KEYCODE_2; 1187eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k3 = KeyEvent.KEYCODE_3; 1188eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k4 = KeyEvent.KEYCODE_4; 1189eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k5 = KeyEvent.KEYCODE_5; 1190eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k6 = KeyEvent.KEYCODE_6; 1191eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k7 = KeyEvent.KEYCODE_7; 1192eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k8 = KeyEvent.KEYCODE_8; 1193eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final int k9 = KeyEvent.KEYCODE_9; 1194eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1195eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The root of the tree doesn't contain any numbers. 1196eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalTimesTree = new Node(); 1197eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mIs24HourView) { 1198eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We'll be re-using these nodes, so we'll save them. 1199eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node minuteFirstDigit = new Node(k0, k1, k2, k3, k4, k5); 1200eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node minuteSecondDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); 1201eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The first digit must be followed by the second digit. 1202eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio minuteFirstDigit.addChild(minuteSecondDigit); 1203eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1204eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The first digit may be 0-1. 1205eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node firstDigit = new Node(k0, k1); 1206eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalTimesTree.addChild(firstDigit); 1207eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1208eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 0-1, the second digit may be 0-5. 1209eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node secondDigit = new Node(k0, k1, k2, k3, k4, k5); 1210eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1211eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We may now be followed by the first minute digit. E.g. 00:09, 15:58. 1212eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(minuteFirstDigit); 1213eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1214eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 0-1, and the second digit is 0-5, the third digit may be 6-9. 1215eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node thirdDigit = new Node(k6, k7, k8, k9); 1216eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The time must now be finished. E.g. 0:55, 1:08. 1217eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(thirdDigit); 1218eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1219eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 0-1, the second digit may be 6-9. 1220eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit = new Node(k6, k7, k8, k9); 1221eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1222eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We must now be followed by the first minute digit. E.g. 06:50, 18:20. 1223eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(minuteFirstDigit); 1224eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1225eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The first digit may be 2. 1226eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit = new Node(k2); 1227eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalTimesTree.addChild(firstDigit); 1228eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1229eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 2, the second digit may be 0-3. 1230eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit = new Node(k0, k1, k2, k3); 1231eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1232eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We must now be followed by the first minute digit. E.g. 20:50, 23:09. 1233eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(minuteFirstDigit); 1234eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1235eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 2, the second digit may be 4-5. 1236eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit = new Node(k4, k5); 1237eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1238eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We must now be followd by the last minute digit. E.g. 2:40, 2:53. 1239eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(minuteSecondDigit); 1240eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1241eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The first digit may be 3-9. 1242eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit = new Node(k3, k4, k5, k6, k7, k8, k9); 1243eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalTimesTree.addChild(firstDigit); 1244eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We must now be followed by the first minute digit. E.g. 3:57, 8:12. 1245eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(minuteFirstDigit); 1246eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } else { 1247eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We'll need to use the AM/PM node a lot. 1248eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Set up AM and PM to respond to "a" and "p". 1249eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node ampm = new Node(getAmOrPmKeyCode(AM), getAmOrPmKeyCode(PM)); 1250eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1251eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The first hour digit may be 1. 1252eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node firstDigit = new Node(k1); 1253eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalTimesTree.addChild(firstDigit); 1254eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We'll allow quick input of on-the-hour times. E.g. 1pm. 1255eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(ampm); 1256eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1257eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 1, the second digit may be 0-2. 1258eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node secondDigit = new Node(k0, k1, k2); 1259eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1260eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // Also for quick input of on-the-hour times. E.g. 10pm, 12am. 1261eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(ampm); 1262eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1263eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 1, and the second digit is 0-2, the third digit may be 0-5. 1264eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node thirdDigit = new Node(k0, k1, k2, k3, k4, k5); 1265eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(thirdDigit); 1266eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The time may be finished now. E.g. 1:02pm, 1:25am. 1267eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit.addChild(ampm); 1268eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1269eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 1, the second digit is 0-2, and the third digit is 0-5, 1270eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // the fourth digit may be 0-9. 1271eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio Node fourthDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); 1272eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit.addChild(fourthDigit); 1273eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The time must be finished now. E.g. 10:49am, 12:40pm. 1274eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio fourthDigit.addChild(ampm); 1275eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1276eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 1, and the second digit is 0-2, the third digit may be 6-9. 1277eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit = new Node(k6, k7, k8, k9); 1278eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(thirdDigit); 1279eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The time must be finished now. E.g. 1:08am, 1:26pm. 1280eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit.addChild(ampm); 1281eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1282eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 1, the second digit may be 3-5. 1283eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit = new Node(k3, k4, k5); 1284eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1285eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1286eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 1, and the second digit is 3-5, the third digit may be 0-9. 1287eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); 1288eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(thirdDigit); 1289eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The time must be finished now. E.g. 1:39am, 1:50pm. 1290eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit.addChild(ampm); 1291eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1292eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The hour digit may be 2-9. 1293eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit = new Node(k2, k3, k4, k5, k6, k7, k8, k9); 1294eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalTimesTree.addChild(firstDigit); 1295eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // We'll allow quick input of on-the-hour-times. E.g. 2am, 5pm. 1296eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(ampm); 1297eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1298eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 2-9, the second digit may be 0-5. 1299eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit = new Node(k0, k1, k2, k3, k4, k5); 1300eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio firstDigit.addChild(secondDigit); 1301eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1302eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // When the first digit is 2-9, and the second digit is 0-5, the third digit may be 0-9. 1303eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); 1304eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio secondDigit.addChild(thirdDigit); 1305eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio // The time must be finished now. E.g. 2:57am, 9:30pm. 1306eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio thirdDigit.addChild(ampm); 1307eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1308eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1309eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1310eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1311eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Simple node class to be used for traversal to check for legal times. 1312eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * mLegalKeys represents the keys that can be typed to get to the node. 1313eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * mChildren are the children that can be reached from this node. 1314eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1315eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private class Node { 1316eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private int[] mLegalKeys; 1317eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private ArrayList<Node> mChildren; 1318eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1319eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public Node(int... legalKeys) { 1320eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mLegalKeys = legalKeys; 1321eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mChildren = new ArrayList<Node>(); 1322eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1323eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1324eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public void addChild(Node child) { 1325eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio mChildren.add(child); 1326eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1327eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1328eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean containsKey(int key) { 1329eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (int i = 0; i < mLegalKeys.length; i++) { 1330eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mLegalKeys[i] == key) { 1331eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return true; 1332eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1333eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1334eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return false; 1335eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1336eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1337eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public Node canReach(int key) { 1338eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (mChildren == null) { 1339eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return null; 1340eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1341eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio for (Node child : mChildren) { 1342eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (child.containsKey(key)) { 1343eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return child; 1344eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1345eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1346eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return null; 1347eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1348eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1349eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1350eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private class KeyboardListener implements View.OnKeyListener { 1351eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio @Override 1352eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio public boolean onKey(View v, int keyCode, KeyEvent event) { 1353eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio if (event.getAction() == KeyEvent.ACTION_UP) { 1354eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return processKeyUp(keyCode); 1355eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1356eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return false; 1357eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1358eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1359eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1360eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio /** 1361eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * Render an animator to pulsate a view in place. 1362eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * 1363eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @param labelToAnimate the view to pulsate. 1364eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio * @return The animator object. Use .start() to begin. 1365eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio */ 1366eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio private static ObjectAnimator getPulseAnimator(View labelToAnimate, float decreaseRatio, 1367eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio float increaseRatio) { 1368eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final Keyframe k0 = Keyframe.ofFloat(0f, 1f); 1369eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final Keyframe k1 = Keyframe.ofFloat(0.275f, decreaseRatio); 1370eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio); 1371eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio final Keyframe k3 = Keyframe.ofFloat(1f, 1f); 1372eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe(View.SCALE_X, k0, k1, k2, k3); 1374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe(View.SCALE_Y, k0, k1, k2, k3); 1375eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio ObjectAnimator pulseAnimator = 1376eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY); 1377eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION); 1378eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio 1379eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio return pulseAnimator; 1380eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio } 1381eeff63a5c347f282b5c8c3ae6a0924bf03fbce8fFabrice Di Meglio} 1382