diff options
author | Fabrice Di Meglio <fdimeglio@google.com> | 2013-08-15 17:49:49 -0700 |
---|---|---|
committer | Fabrice Di Meglio <fdimeglio@google.com> | 2013-08-16 14:34:25 -0700 |
commit | 64902bd89ea0630a59eb61345061002e9895af84 (patch) | |
tree | 7f1f20ab9613f64020c1547c1cc29b16d9a5df8e | |
parent | 80f7ec06d0e45a8724122d5b4451ee12e37f9aac (diff) | |
download | frameworks_base-64902bd89ea0630a59eb61345061002e9895af84.zip frameworks_base-64902bd89ea0630a59eb61345061002e9895af84.tar.gz frameworks_base-64902bd89ea0630a59eb61345061002e9895af84.tar.bz2 |
Fix old remaining i18n bugs on TimePicker:
- put am/pm on the left side of hours for hu, zh, ja and ko Locales
- use the hours/minutes separator from the Locale (fi, sr, ...)
- updated layouts (better for Arabic, Farsi and Hebrew)
- support double digits format for 12h and single digit format for
24h (it, ja, vi, ...)
- fix setIs24HourView(boolean) behavior: do not lose the current hour
value when switching from 12h to 24h
Change-Id: If66cb6f802d894f0a2357b43eede6854791f3b67
-rw-r--r-- | core/java/android/widget/TimePicker.java | 115 | ||||
-rw-r--r-- | core/res/res/layout/time_picker.xml | 1 | ||||
-rw-r--r-- | core/res/res/layout/time_picker_holo.xml | 15 | ||||
-rw-r--r-- | core/res/res/values/donottranslate.xml | 2 | ||||
-rwxr-xr-x | core/res/res/values/symbols.xml | 2 |
5 files changed, 117 insertions, 18 deletions
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index e33c4d4..1c1d77a 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -22,10 +22,12 @@ import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcelable; +import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.inputmethod.EditorInfo; @@ -105,6 +107,9 @@ public class TimePicker extends FrameLayout { private Locale mCurrentLocale; + private boolean mHourWithTwoDigit; + private char mHourFormat; + /** * The callback interface used to indicate the time has been adjusted. */ @@ -164,7 +169,7 @@ public class TimePicker extends FrameLayout { // divider (only for the new widget style) mDivider = (TextView) findViewById(R.id.divider); if (mDivider != null) { - mDivider.setText(R.string.time_picker_separator); + setDividerText(); } // minute @@ -235,6 +240,24 @@ public class TimePicker extends FrameLayout { mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE); } + if (isAmPmAtStart()) { + // Move the am/pm view to the beginning + ViewGroup amPmParent = (ViewGroup) findViewById(R.id.timePickerLayout); + amPmParent.removeView(amPmView); + amPmParent.addView(amPmView, 0); + // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme for + // example and not for Holo Theme) + ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams(); + final int startMargin = lp.getMarginStart(); + final int endMargin = lp.getMarginEnd(); + if (startMargin != endMargin) { + lp.setMarginStart(endMargin); + lp.setMarginEnd(startMargin); + } + } + + getHourFormatData(); + // update controls to initial state updateHourControl(); updateMinuteControl(); @@ -259,6 +282,35 @@ public class TimePicker extends FrameLayout { } } + private void getHourFormatData() { + final Locale defaultLocale = Locale.getDefault(); + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale, + (mIs24HourView) ? "Hm" : "hm"); + final int lengthPattern = bestDateTimePattern.length(); + mHourWithTwoDigit = false; + char hourFormat = '\0'; + // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save + // the hour format that we found. + for (int i = 0; i < lengthPattern; i++) { + final char c = bestDateTimePattern.charAt(i); + if (c == 'H' || c == 'h' || c == 'K' || c == 'k') { + mHourFormat = c; + if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) { + mHourWithTwoDigit = true; + } + break; + } + } + } + + private boolean isAmPmAtStart() { + final Locale defaultLocale = Locale.getDefault(); + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale, + "hm" /* skeleton */); + + return bestDateTimePattern.startsWith("a"); + } + @Override public void setEnabled(boolean enabled) { if (mIsEnabled == enabled) { @@ -423,9 +475,11 @@ public class TimePicker extends FrameLayout { if (mIs24HourView == is24HourView) { return; } - mIs24HourView = is24HourView; - // cache the current hour since spinner range changes + // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!! int currentHour = getCurrentHour(); + // Order is important here. + mIs24HourView = is24HourView; + getHourFormatData(); updateHourControl(); // set value after spinner range is updated setCurrentHour(currentHour); @@ -458,6 +512,38 @@ public class TimePicker extends FrameLayout { onTimeChanged(); } + /** + * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":". + * + * See http://unicode.org/cldr/trac/browser/trunk/common/main + * + * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the + * separator as the character which is just after the hour marker in the returned pattern. + */ + private void setDividerText() { + final Locale defaultLocale = Locale.getDefault(); + final String skeleton = (mIs24HourView) ? "Hm" : "hm"; + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale, + skeleton); + final String separatorText; + int hourIndex = bestDateTimePattern.lastIndexOf('H'); + if (hourIndex == -1) { + hourIndex = bestDateTimePattern.lastIndexOf('h'); + } + if (hourIndex == -1) { + // Default case + separatorText = ":"; + } else { + int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1); + if (minuteIndex == -1) { + separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1)); + } else { + separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex); + } + } + mDivider.setText(separatorText); + } + @Override public int getBaseline() { return mHourSpinner.getBaseline(); @@ -500,14 +586,25 @@ public class TimePicker extends FrameLayout { private void updateHourControl() { if (is24HourView()) { - mHourSpinner.setMinValue(0); - mHourSpinner.setMaxValue(23); - mHourSpinner.setFormatter(NumberPicker.getTwoDigitFormatter()); + // 'k' means 1-24 hour + if (mHourFormat == 'k') { + mHourSpinner.setMinValue(1); + mHourSpinner.setMaxValue(24); + } else { + mHourSpinner.setMinValue(0); + mHourSpinner.setMaxValue(23); + } } else { - mHourSpinner.setMinValue(1); - mHourSpinner.setMaxValue(12); - mHourSpinner.setFormatter(null); + // 'K' means 0-11 hour + if (mHourFormat == 'K') { + mHourSpinner.setMinValue(0); + mHourSpinner.setMaxValue(11); + } else { + mHourSpinner.setMinValue(1); + mHourSpinner.setMaxValue(12); + } } + mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null); } private void updateMinuteControl() { diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml index a78cd85..4fa94f3 100644 --- a/core/res/res/layout/time_picker.xml +++ b/core/res/res/layout/time_picker.xml @@ -20,6 +20,7 @@ <!-- Layout of time picker--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/timePickerLayout" android:orientation="horizontal" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml index 7d8900e..c6b7d3a 100644 --- a/core/res/res/layout/time_picker_holo.xml +++ b/core/res/res/layout/time_picker_holo.xml @@ -20,14 +20,19 @@ <!-- Layout of time picker --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/timePickerLayout" android:orientation="horizontal" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:paddingStart="8dip" + android:paddingEnd="8dip"> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingStart="8dip" + android:paddingEnd="8dip" android:layoutDirection="ltr"> <!-- hour --> @@ -37,8 +42,6 @@ android:layout_height="wrap_content" android:layout_marginTop="16dip" android:layout_marginBottom="16dip" - android:layout_marginStart="16dip" - android:layout_marginEnd="6dip" android:focusable="true" android:focusableInTouchMode="true" /> @@ -48,6 +51,8 @@ android:id="@+id/divider" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="6dip" + android:layout_marginEnd="6dip" android:layout_gravity="center_vertical" android:importantForAccessibility="no" /> @@ -59,8 +64,6 @@ android:layout_height="wrap_content" android:layout_marginTop="16dip" android:layout_marginBottom="16dip" - android:layout_marginStart="6dip" - android:layout_marginEnd="8dip" android:focusable="true" android:focusableInTouchMode="true" /> @@ -75,7 +78,7 @@ android:layout_marginTop="16dip" android:layout_marginBottom="16dip" android:layout_marginStart="8dip" - android:layout_marginEnd="16dip" + android:layout_marginEnd="8dip" android:focusable="true" android:focusableInTouchMode="true" /> diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml index b49e7bd..a7288e1 100644 --- a/core/res/res/values/donottranslate.xml +++ b/core/res/res/values/donottranslate.xml @@ -24,8 +24,6 @@ <bool name="lockscreen_isPortrait">true</bool> <!-- @hide DO NOT TRANSLATE. Control aspect ratio of lock pattern --> <string name="lock_pattern_view_aspect">square</string> - <!-- @hide DO NOT TRANSLATE. Separator between the hour and minute elements in a TimePicker widget --> - <string name="time_picker_separator">:</string> <!-- @hide DO NOT TRANSLATE. ICU pattern for "Mon, 14 January" --> <string name="icu_abbrev_wday_month_day_no_year">eeeMMMMd</string> <!-- @hide DO NOT TRANSLATE. date formatting pattern for system ui.--> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 14ae1e6..ca93d1c 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -217,6 +217,7 @@ <java-symbol type="id" name="pin_new_text" /> <java-symbol type="id" name="pin_confirm_text" /> <java-symbol type="id" name="pin_error_message" /> + <java-symbol type="id" name="timePickerLayout" /> <java-symbol type="attr" name="actionModeShareDrawable" /> <java-symbol type="attr" name="alertDialogCenterButtons" /> @@ -773,7 +774,6 @@ <java-symbol type="string" name="time_picker_increment_hour_button" /> <java-symbol type="string" name="time_picker_increment_minute_button" /> <java-symbol type="string" name="time_picker_increment_set_pm_button" /> - <java-symbol type="string" name="time_picker_separator" /> <java-symbol type="string" name="upload_file" /> <java-symbol type="string" name="user_switched" /> <java-symbol type="string" name="volume_alarm" /> |