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 PickerConstants.Time mConstant; 37 38 private boolean mIs24hFormat = false; 39 private boolean mPendingTime = false; 40 private int mInitHour; 41 private int mInitMinute; 42 private boolean mInitIsPm; 43 44 // Column order varies by locale 45 public static class ColumnOrder { 46 public int hours = 0; 47 public int minutes = 1; 48 public int amPm = 2; 49 50 public ColumnOrder(boolean is24hFormat) { 51 Locale locale = Locale.getDefault(); 52 String hmaPattern = DateFormat.getBestDateTimePattern(locale, "hma"); 53 boolean isAmPmAtEnd = hmaPattern.indexOf("a") > hmaPattern.indexOf("m"); 54 boolean isRtl = TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL; 55 // Note ordering of calculation below is important 56 57 if (isRtl) { 58 // Hours and minutes are always shown with hours on the left 59 hours = 1; 60 minutes = 0; 61 } 62 if (!isAmPmAtEnd && !is24hFormat) { 63 // Rotate AM/PM indicator to front, if visible 64 amPm = 0; 65 hours++; 66 minutes++; 67 } 68 } 69 } 70 71 private ColumnOrder mColumnOrder; 72 73 public static TimePicker newInstance() { 74 return newInstance(true, true); 75 } 76 77 public static TimePicker newInstance(boolean is24hFormat, boolean defaultToCurrentTime) { 78 TimePicker picker = new TimePicker(); 79 Bundle args = new Bundle(); 80 args.putBoolean(EXTRA_24H_FORMAT, is24hFormat); 81 args.putBoolean(EXTRA_DEFAULT_TO_CURRENT, defaultToCurrentTime); 82 picker.setArguments(args); 83 return picker; 84 } 85 86 @Override 87 public void onCreate(Bundle savedInstanceState) { 88 mIs24hFormat = getArguments().getBoolean(EXTRA_24H_FORMAT, false); 89 boolean useCurrent = getArguments().getBoolean(EXTRA_DEFAULT_TO_CURRENT, false); 90 mColumnOrder = new ColumnOrder(mIs24hFormat); 91 92 super.onCreate(savedInstanceState); 93 94 mConstant = PickerConstants.getTimeInstance(getResources()); 95 96 if (useCurrent) { 97 mPendingTime = true; 98 Calendar cal = Calendar.getInstance(); 99 mInitHour = cal.get(Calendar.HOUR_OF_DAY); 100 101 if (!mIs24hFormat) { 102 if (mInitHour >= HOURS_IN_HALF_DAY) { 103 // PM case, valid hours: 12-23 104 mInitIsPm = true; 105 if (mInitHour > HOURS_IN_HALF_DAY) { 106 mInitHour = mInitHour - HOURS_IN_HALF_DAY; 107 } 108 } else { 109 // AM case, valid hours: 0-11 110 mInitIsPm = false; 111 if (mInitHour == 0) { 112 mInitHour = HOURS_IN_HALF_DAY; 113 } 114 } 115 } 116 117 mInitMinute = cal.get(Calendar.MINUTE); 118 } 119 } 120 121 @Override 122 public void onResume() { 123 if (mPendingTime) { 124 mPendingTime = false; 125 setTime(mInitHour, mInitMinute, mInitIsPm); 126 } 127 super.onResume(); 128 } 129 130 protected boolean setTime(int hour, int minute, boolean isPm) { 131 if (minute < 0 || minute > 59) { 132 return false; 133 } 134 135 if (mIs24hFormat) { 136 if (hour < 0 || hour > 23) { 137 return false; 138 } 139 } else { 140 if (hour < 1 || hour > 12) { 141 return false; 142 } 143 } 144 145 updateSelection(mColumnOrder.hours, mIs24hFormat ? hour : (hour - 1)); 146 updateSelection(mColumnOrder.minutes, minute); 147 if (!mIs24hFormat) { 148 updateSelection(mColumnOrder.amPm, isPm ? 1 : 0); 149 } 150 151 return true; 152 } 153 154 @Override 155 protected ArrayList<PickerColumn> getColumns() { 156 ArrayList<PickerColumn> ret = new ArrayList<>(); 157 // Fill output with nulls, then place actual columns according to order 158 int capacity = mIs24hFormat ? 2 : 3; 159 for (int i = 0; i < capacity; i++) { 160 ret.add(null); 161 } 162 PickerColumn hours = new PickerColumn(mIs24hFormat ? mConstant.hours24 : mConstant.hours12); 163 PickerColumn minutes = new PickerColumn(mConstant.minutes); 164 ret.set(mColumnOrder.hours, hours); 165 ret.set(mColumnOrder.minutes, minutes); 166 167 if (!mIs24hFormat) { 168 PickerColumn ampm = new PickerColumn(mConstant.ampm); 169 ret.set(mColumnOrder.amPm, ampm); 170 } 171 return ret; 172 } 173 174 @Override 175 protected String getSeparator() { 176 return mConstant.timeSeparator; 177 } 178 } 179