1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.settings.widget.picker; 18 19 import android.os.Bundle; 20 import android.text.format.DateFormat; 21 import android.text.TextUtils; 22 import android.view.View; 23 24 import java.util.ArrayList; 25 import java.util.Calendar; 26 import java.util.Locale; 27 28 29 public class TimePicker extends Picker { 30 31 private static final String EXTRA_24H_FORMAT = "24h_format"; 32 private static final String EXTRA_DEFAULT_TO_CURRENT = "delault_to_current"; 33 34 private static final int HOURS_IN_HALF_DAY = 12; 35 36 private boolean mIs24hFormat = false; 37 private boolean mPendingTime = false; 38 private int mInitHour; 39 private int mInitMinute; 40 private boolean mInitIsPm; 41 42 // Column order varies by locale 43 private static class ColumnOrder { 44 int mHours = 0; 45 int mMinutes = 1; 46 int mAmPm = 2; 47 } 48 private ColumnOrder mColumnOrder = new ColumnOrder(); 49 newInstance()50 public static TimePicker newInstance() { 51 return newInstance(true, true); 52 } 53 newInstance(boolean is24hFormat, boolean defaultToCurrentTime)54 public static TimePicker newInstance(boolean is24hFormat, boolean defaultToCurrentTime) { 55 TimePicker picker = new TimePicker(); 56 Bundle args = new Bundle(); 57 args.putBoolean(EXTRA_24H_FORMAT, is24hFormat); 58 args.putBoolean(EXTRA_DEFAULT_TO_CURRENT, defaultToCurrentTime); 59 picker.setArguments(args); 60 return picker; 61 } 62 63 @Override onCreate(Bundle savedInstanceState)64 public void onCreate(Bundle savedInstanceState) { 65 mIs24hFormat = getArguments().getBoolean(EXTRA_24H_FORMAT, false); 66 boolean useCurrent = getArguments().getBoolean(EXTRA_DEFAULT_TO_CURRENT, false); 67 68 super.onCreate(savedInstanceState); 69 70 if (useCurrent) { 71 mPendingTime = true; 72 Calendar cal = Calendar.getInstance(); 73 mInitHour = cal.get(Calendar.HOUR_OF_DAY); 74 75 if (!mIs24hFormat) { 76 if (mInitHour >= HOURS_IN_HALF_DAY) { 77 // PM case, valid hours: 12-23 78 mInitIsPm = true; 79 if (mInitHour > HOURS_IN_HALF_DAY) { 80 mInitHour = mInitHour - HOURS_IN_HALF_DAY; 81 } 82 } else { 83 // AM case, valid hours: 0-11 84 mInitIsPm = false; 85 if (mInitHour == 0) { 86 mInitHour = HOURS_IN_HALF_DAY; 87 } 88 } 89 } 90 91 mInitMinute = cal.get(Calendar.MINUTE); 92 } 93 94 Locale locale = Locale.getDefault(); 95 String hmaPattern = DateFormat.getBestDateTimePattern(locale, "hma"); 96 boolean isAmPmAtEnd = hmaPattern.indexOf("a") > hmaPattern.indexOf("m"); 97 boolean isRtl = TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL; 98 // Note ordering of calculation below is important 99 if (isRtl) { 100 // Hours and minutes are always shown with hours on the left 101 mColumnOrder.mHours = 1; 102 mColumnOrder.mMinutes = 0; 103 } 104 if (!isAmPmAtEnd && !mIs24hFormat) { 105 // Rotate AM/PM indicator to front, if visible 106 mColumnOrder.mAmPm = 0; 107 mColumnOrder.mHours++; 108 mColumnOrder.mMinutes++; 109 } 110 } 111 112 @Override onResume()113 public void onResume() { 114 if (mPendingTime) { 115 mPendingTime = false; 116 setTime(mInitHour, mInitMinute, mInitIsPm); 117 } 118 super.onResume(); 119 } 120 setTime(int hour, int minute, boolean isPm)121 protected boolean setTime(int hour, int minute, boolean isPm) { 122 if (minute < 0 || minute > 59) { 123 return false; 124 } 125 126 if (mIs24hFormat) { 127 if (hour < 0 || hour > 23) { 128 return false; 129 } 130 } else { 131 if (hour < 1 || hour > 12) { 132 return false; 133 } 134 } 135 136 updateSelection(mColumnOrder.mHours, mIs24hFormat ? hour : (hour - 1)); 137 updateSelection(mColumnOrder.mMinutes, minute); 138 if (!mIs24hFormat) { 139 updateSelection(mColumnOrder.mAmPm, isPm ? 1 : 0); 140 } 141 142 return true; 143 } 144 145 @Override getColumns()146 protected ArrayList<PickerColumn> getColumns() { 147 ArrayList<PickerColumn> ret = new ArrayList<PickerColumn>(); 148 // Fill output with nulls, then place actual columns according to order 149 int capacity = mIs24hFormat ? 2 : 3; 150 for (int i = 0; i < capacity; i++) { 151 ret.add(null); 152 } 153 PickerColumn hours = new PickerColumn(mIs24hFormat ? mConstant.hours24 : mConstant.hours12); 154 PickerColumn minutes = new PickerColumn(mConstant.minutes); 155 ret.set(mColumnOrder.mHours, hours); 156 ret.set(mColumnOrder.mMinutes, minutes); 157 158 if (!mIs24hFormat) { 159 PickerColumn ampm = new PickerColumn(mConstant.ampm); 160 ret.set(mColumnOrder.mAmPm, ampm); 161 } 162 return ret; 163 } 164 165 @Override getSeparator()166 protected String getSeparator() { 167 return mConstant.timeSeparator; 168 } 169 } 170