summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2014-10-15 13:20:47 -0700
committerAlan Viverette <alanv@google.com>2014-10-15 13:20:54 -0700
commit67945c11a5e9547f71be91ceb99e7b9ff15a6292 (patch)
treef0beb0b28867afc714d82062f9ae1a2c8c93f2f4 /core
parent9e18d7ab70eb581200afe0abbd1bb6e32f9e135d (diff)
downloadframeworks_base-67945c11a5e9547f71be91ceb99e7b9ff15a6292.zip
frameworks_base-67945c11a5e9547f71be91ceb99e7b9ff15a6292.tar.gz
frameworks_base-67945c11a5e9547f71be91ceb99e7b9ff15a6292.tar.bz2
Update AM/PM selectors for clock face TimePicker
The selectors are now CheckedTextViews, which makes more sense when using a screen reader. BUG: 17468036 Change-Id: I09c62a08172a710faa8fb7ed2bf99a66331e5701
Diffstat (limited to 'core')
-rw-r--r--core/java/android/widget/RadialTimePickerView.java269
-rw-r--r--core/java/android/widget/TimePickerClockDelegate.java2
-rw-r--r--core/java/android/widget/TimePickerSpinnerDelegate.java180
-rw-r--r--core/res/res/layout/time_header_label.xml36
-rw-r--r--core/res/res/values/dimens.xml15
-rw-r--r--core/res/res/values/symbols.xml4
6 files changed, 179 insertions, 327 deletions
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 56f126c..d15f2d6 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -22,9 +22,7 @@ import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
-import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -47,7 +45,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.R;
-import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
@@ -69,7 +66,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
private static final int HOURS = 0;
private static final int MINUTES = 1;
private static final int HOURS_INNER = 2;
- private static final int AMPM = 3;
private static final int SELECTOR_CIRCLE = 0;
private static final int SELECTOR_DOT = 1;
@@ -87,12 +83,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
// Alpha level of color for selector.
private static final int ALPHA_SELECTOR = 60; // was 51
- // Alpha level of color for selected circle.
- private static final int ALPHA_AMPM_SELECTED = ALPHA_SELECTOR;
-
- // Alpha level of color for pressed circle.
- private static final int ALPHA_AMPM_PRESSED = 255; // was 175
-
private static final float COSINE_30_DEGREES = ((float) Math.sqrt(3)) * 0.5f;
private static final float SINE_30_DEGREES = 0.5f;
@@ -105,8 +95,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
private static final int CENTER_RADIUS = 2;
- private static final int[] STATE_SET_SELECTED = new int[] {R.attr.state_selected};
-
private static int[] sSnapPrefer30sMap = new int[361];
private final String[] mHours12Texts = new String[12];
@@ -114,8 +102,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
private final String[] mInnerHours24Texts = new String[12];
private final String[] mMinutesTexts = new String[12];
- private final String[] mAmPmText = new String[2];
-
private final Paint[] mPaint = new Paint[2];
private final int[] mColor = new int[2];
private final IntHolder[] mAlpha = new IntHolder[2];
@@ -126,11 +112,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
private final int[][] mColorSelector = new int[2][3];
private final IntHolder[][] mAlphaSelector = new IntHolder[2][3];
- private final Paint mPaintAmPmText = new Paint();
- private final Paint[] mPaintAmPmCircle = new Paint[2];
-
private final Paint mPaintBackground = new Paint();
- private final Paint mPaintDisabled = new Paint();
private final Paint mPaintDebug = new Paint();
private Typeface mTypeface;
@@ -184,21 +166,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
private float mSelectionRadiusMultiplier;
private int[] mSelectionDegrees = new int[3];
- private int mAmPmCircleRadius;
- private float mAmPmYCenter;
-
- private float mAmPmCircleRadiusMultiplier;
- private int mAmPmTextColor;
-
- private float mLeftIndicatorXCenter;
- private float mRightIndicatorXCenter;
-
- private int mAmPmUnselectedColor;
- private int mAmPmSelectedColor;
-
private int mAmOrPm;
- private int mAmOrPmPressed;
-
private int mDisabledAlpha;
private RectF mRectF = new RectF();
@@ -331,27 +299,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TimePicker,
defStyle, 0);
- ColorStateList amPmBackgroundColor = a.getColorStateList(
- R.styleable.TimePicker_amPmBackgroundColor);
- if (amPmBackgroundColor == null) {
- amPmBackgroundColor = res.getColorStateList(
- R.color.timepicker_default_ampm_unselected_background_color_material);
- }
-
- // Obtain the backup selected color. If the background color state
- // list doesn't have a state for selected, we'll use this color.
- final int amPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor,
- res.getColor(R.color.timepicker_default_ampm_selected_background_color_material));
- amPmBackgroundColor = ColorStateList.addFirstIfMissing(
- amPmBackgroundColor, R.attr.state_selected, amPmSelectedColor);
-
- mAmPmSelectedColor = amPmBackgroundColor.getColorForState(
- STATE_SET_SELECTED, amPmSelectedColor);
- mAmPmUnselectedColor = amPmBackgroundColor.getDefaultColor();
-
- mAmPmTextColor = a.getColor(R.styleable.TimePicker_amPmTextColor,
- res.getColor(R.color.timepicker_default_text_color_material));
-
mTypeface = Typeface.create("sans-serif", Typeface.NORMAL);
// Initialize all alpha values to opaque.
@@ -419,16 +366,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
R.styleable.TimePicker_numbersSelectorColor,
R.color.timepicker_default_selector_color_material);
- mPaintAmPmText.setColor(mAmPmTextColor);
- mPaintAmPmText.setTypeface(mTypeface);
- mPaintAmPmText.setAntiAlias(true);
- mPaintAmPmText.setTextAlign(Paint.Align.CENTER);
-
- mPaintAmPmCircle[AM] = new Paint();
- mPaintAmPmCircle[AM].setAntiAlias(true);
- mPaintAmPmCircle[PM] = new Paint();
- mPaintAmPmCircle[PM].setAntiAlias(true);
-
mPaintBackground.setColor(a.getColor(R.styleable.TimePicker_numbersBackgroundColor,
res.getColor(R.color.timepicker_default_numbers_background_color_material)));
mPaintBackground.setAntiAlias(true);
@@ -444,7 +381,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
mShowHours = true;
mIs24HourMode = false;
mAmOrPm = AM;
- mAmOrPmPressed = -1;
initHoursAndMinutesText();
initData();
@@ -530,13 +466,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
// 0 is 12 AM (midnight) and 12 is 12 PM (noon).
mAmOrPm = (hour == 0 || (hour % 24) < 12) ? AM : PM;
-
- if (mIs24HourMode) {
- // Inner circle is 1 through 12.
- mIsOnInnerCircle = hour >= 1 && hour <= 12;
- } else {
- mIsOnInnerCircle = false;
- }
+ mIsOnInnerCircle = mIs24HourMode && hour >= 1 && hour <= 12;
initData();
updateLayoutData();
@@ -586,11 +516,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
return mAmOrPm;
}
- public void swapAmPm() {
- mAmOrPm = (mAmOrPm == AM) ? PM : AM;
- invalidate();
- }
-
public void showHours(boolean animate) {
if (mShowHours) return;
mShowHours = true;
@@ -621,10 +546,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
mInnerHours24Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
mMinutesTexts[i] = String.format("%02d", MINUTES_NUMBERS[i]);
}
-
- String[] amPmStrings = TimePickerClockDelegate.getAmPmStrings(mContext);
- mAmPmText[AM] = amPmStrings[0];
- mAmPmText[PM] = amPmStrings[1];
}
private void initData() {
@@ -674,9 +595,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
mAnimationRadiusMultiplier[HOURS_INNER] = 1;
mAnimationRadiusMultiplier[MINUTES] = 1;
- mAmPmCircleRadiusMultiplier = Float.parseFloat(
- res.getString(R.string.timepicker_ampm_circle_radius_multiplier));
-
mAlpha[HOURS].setValue(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
mAlpha[MINUTES].setValue(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
@@ -710,14 +628,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
mCircleRadius[HOURS_INNER] = min * mCircleRadiusMultiplier[HOURS];
mCircleRadius[MINUTES] = min * mCircleRadiusMultiplier[MINUTES];
- if (!mIs24HourMode) {
- // We'll need to draw the AM/PM circles, so the main circle will need to have
- // a slightly higher center. To keep the entire view centered vertically, we'll
- // have to push it up by half the radius of the AM/PM circles.
- int amPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
- mYCenter -= amPmCircleRadius / 2;
- }
-
mMinHypotenuseForInnerNumber = (int) (mCircleRadius[HOURS]
* mNumbersRadiusMultiplier[HOURS_INNER]) - mSelectionRadius[HOURS];
mMaxHypotenuseForOuterNumber = (int) (mCircleRadius[HOURS]
@@ -738,17 +648,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
mSelectionRadius[HOURS] = (int) (mCircleRadius[HOURS] * mSelectionRadiusMultiplier);
mSelectionRadius[HOURS_INNER] = mSelectionRadius[HOURS];
mSelectionRadius[MINUTES] = (int) (mCircleRadius[MINUTES] * mSelectionRadiusMultiplier);
-
- mAmPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
- mPaintAmPmText.setTextSize(mAmPmCircleRadius * 3 / 4);
-
- // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
- mAmPmYCenter = mYCenter + mCircleRadius[HOURS];
-
- // Line up the horizontal edges of the AM/PM circles with the horizontal edges
- // of the main circle
- mLeftIndicatorXCenter = mXCenter - mCircleRadius[HOURS] + mAmPmCircleRadius;
- mRightIndicatorXCenter = mXCenter + mCircleRadius[HOURS] - mAmPmCircleRadius;
}
@Override
@@ -780,9 +679,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
mColor[MINUTES], mAlpha[MINUTES].getValue());
drawCenter(canvas);
- if (!mIs24HourMode) {
- drawAmPm(canvas);
- }
if (DEBUG) {
drawDebug(canvas);
@@ -804,50 +700,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
drawSelector(canvas, MINUTES);
}
- private void drawAmPm(Canvas canvas) {
- final boolean isLayoutRtl = isLayoutRtl();
-
- int amColor = mAmPmUnselectedColor;
- int amAlpha = ALPHA_OPAQUE;
- int pmColor = mAmPmUnselectedColor;
- int pmAlpha = ALPHA_OPAQUE;
- if (mAmOrPm == AM) {
- amColor = mAmPmSelectedColor;
- amAlpha = ALPHA_AMPM_SELECTED;
- } else if (mAmOrPm == PM) {
- pmColor = mAmPmSelectedColor;
- pmAlpha = ALPHA_AMPM_SELECTED;
- }
- if (mAmOrPmPressed == AM) {
- amColor = mAmPmSelectedColor;
- amAlpha = ALPHA_AMPM_PRESSED;
- } else if (mAmOrPmPressed == PM) {
- pmColor = mAmPmSelectedColor;
- pmAlpha = ALPHA_AMPM_PRESSED;
- }
-
- // Draw the two circles
- mPaintAmPmCircle[AM].setColor(amColor);
- mPaintAmPmCircle[AM].setAlpha(getMultipliedAlpha(amColor, amAlpha));
- canvas.drawCircle(isLayoutRtl ? mRightIndicatorXCenter : mLeftIndicatorXCenter,
- mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[AM]);
-
- mPaintAmPmCircle[PM].setColor(pmColor);
- mPaintAmPmCircle[PM].setAlpha(getMultipliedAlpha(pmColor, pmAlpha));
- canvas.drawCircle(isLayoutRtl ? mLeftIndicatorXCenter : mRightIndicatorXCenter,
- mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[PM]);
-
- // Draw the AM/PM texts on top
- mPaintAmPmText.setColor(mAmPmTextColor);
- float textYCenter = mAmPmYCenter -
- (int) (mPaintAmPmText.descent() + mPaintAmPmText.ascent()) / 2;
-
- canvas.drawText(isLayoutRtl ? mAmPmText[PM] : mAmPmText[AM], mLeftIndicatorXCenter,
- textYCenter, mPaintAmPmText);
- canvas.drawText(isLayoutRtl ? mAmPmText[AM] : mAmPmText[PM], mRightIndicatorXCenter,
- textYCenter, mPaintAmPmText);
- }
-
private int getMultipliedAlpha(int argb, int alpha) {
return (int) (Color.alpha(argb) * (alpha / 255.0) + 0.5);
}
@@ -950,7 +802,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
float x = mXCenter - width / 2;
float y = mYCenter + 1.5f * height;
- canvas.drawText(selected.toString(), x, y, paint);
+ canvas.drawText(selected, x, y, paint);
}
private void calculateGridSizesHours() {
@@ -1259,26 +1111,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
return (int) degrees;
}
- private int getIsTouchingAmOrPm(float x, float y) {
- final boolean isLayoutRtl = isLayoutRtl();
- int squaredYDistance = (int) ((y - mAmPmYCenter) * (y - mAmPmYCenter));
-
- int distanceToAmCenter = (int) Math.sqrt(
- (x - mLeftIndicatorXCenter) * (x - mLeftIndicatorXCenter) + squaredYDistance);
- if (distanceToAmCenter <= mAmPmCircleRadius) {
- return (isLayoutRtl ? PM : AM);
- }
-
- int distanceToPmCenter = (int) Math.sqrt(
- (x - mRightIndicatorXCenter) * (x - mRightIndicatorXCenter) + squaredYDistance);
- if (distanceToPmCenter <= mAmPmCircleRadius) {
- return (isLayoutRtl ? AM : PM);
- }
-
- // Neither was close enough.
- return -1;
- }
-
@Override
public boolean onTouch(View v, MotionEvent event) {
if(!mInputEnabled) {
@@ -1295,75 +1127,53 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
- mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
- if (mAmOrPmPressed != -1) {
- result = true;
- } else {
- degrees = getDegreesFromXY(eventX, eventY);
- if (degrees != -1) {
- snapDegrees = (mShowHours ?
- snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+ degrees = getDegreesFromXY(eventX, eventY);
+ if (degrees != -1) {
+ snapDegrees = (mShowHours ?
+ snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+ if (mShowHours) {
+ mSelectionDegrees[HOURS] = snapDegrees;
+ mSelectionDegrees[HOURS_INNER] = snapDegrees;
+ } else {
+ mSelectionDegrees[MINUTES] = snapDegrees;
+ }
+ performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+ if (mListener != null) {
if (mShowHours) {
- mSelectionDegrees[HOURS] = snapDegrees;
- mSelectionDegrees[HOURS_INNER] = snapDegrees;
- } else {
- mSelectionDegrees[MINUTES] = snapDegrees;
- }
- performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
- if (mListener != null) {
- if (mShowHours) {
- mListener.onValueSelected(HOURS, getCurrentHour(), false);
- } else {
- mListener.onValueSelected(MINUTES, getCurrentMinute(), false);
- }
+ mListener.onValueSelected(HOURS, getCurrentHour(), false);
+ } else {
+ mListener.onValueSelected(MINUTES, getCurrentMinute(), false);
}
- result = true;
}
+ result = true;
+ invalidate();
}
- invalidate();
- return result;
+ break;
case MotionEvent.ACTION_UP:
- mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
- if (mAmOrPmPressed != -1) {
- if (mAmOrPm != mAmOrPmPressed) {
- swapAmPm();
+ degrees = getDegreesFromXY(eventX, eventY);
+ if (degrees != -1) {
+ snapDegrees = (mShowHours ?
+ snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+ if (mShowHours) {
+ mSelectionDegrees[HOURS] = snapDegrees;
+ mSelectionDegrees[HOURS_INNER] = snapDegrees;
+ } else {
+ mSelectionDegrees[MINUTES] = snapDegrees;
}
- mAmOrPmPressed = -1;
if (mListener != null) {
- mListener.onValueSelected(AMPM, getCurrentHour(), true);
- }
- result = true;
- } else {
- degrees = getDegreesFromXY(eventX, eventY);
- if (degrees != -1) {
- snapDegrees = (mShowHours ?
- snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
if (mShowHours) {
- mSelectionDegrees[HOURS] = snapDegrees;
- mSelectionDegrees[HOURS_INNER] = snapDegrees;
- } else {
- mSelectionDegrees[MINUTES] = snapDegrees;
+ mListener.onValueSelected(HOURS, getCurrentHour(), true);
+ } else {
+ mListener.onValueSelected(MINUTES, getCurrentMinute(), true);
}
- if (mListener != null) {
- if (mShowHours) {
- mListener.onValueSelected(HOURS, getCurrentHour(), true);
- } else {
- mListener.onValueSelected(MINUTES, getCurrentMinute(), true);
- }
- }
- result = true;
}
- }
- if (result) {
invalidate();
+ result = true;
}
- return result;
-
- default:
break;
}
- return false;
+ return result;
}
/**
@@ -1373,8 +1183,8 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
}
/**
@@ -1404,7 +1214,6 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
* When scroll forward/backward events are received, jump the time to the higher/lower
* discrete, visible value on the circle.
*/
- @SuppressLint("NewApi")
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
if (super.performAccessibilityAction(action, arguments)) {
@@ -1418,8 +1227,8 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
changeMultiplier = -1;
}
if (changeMultiplier != 0) {
- int value = 0;
- int stepSize = 0;
+ int value;
+ final int stepSize;
if (mShowHours) {
stepSize = DEGREES_FOR_ONE_HOUR;
value = getCurrentHour() % 12;
@@ -1431,7 +1240,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
int degrees = value * stepSize;
degrees = snapOnly30s(degrees, changeMultiplier);
value = degrees / stepSize;
- int maxValue = 0;
+ final int maxValue;
int minValue = 0;
if (mShowHours) {
if (mIs24HourMode) {
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index 8917f39..6dfea92 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -43,7 +43,7 @@ import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
/**
- * A delegate implementing the basic TimePicker
+ * A delegate implementing the basic spinner-based TimePicker.
*/
class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate {
private static final boolean DEFAULT_ENABLED_STATE = true;
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 73e05e8..e4342b1 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -28,6 +28,7 @@ import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -44,7 +45,7 @@ import java.util.Calendar;
import java.util.Locale;
/**
- * A view for selecting the time of day, in either 24 hour or AM/PM mode.
+ * A delegate implementing the radial clock-based TimePicker.
*/
class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate implements
RadialTimePickerView.OnValueSelectedListener {
@@ -61,23 +62,27 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
// Also NOT a real index, just used for keyboard mode.
private static final int ENABLE_PICKER_INDEX = 3;
- private static final int AM = 0;
- private static final int PM = 1;
+ static final int AM = 0;
+ static final int PM = 1;
private static final boolean DEFAULT_ENABLED_STATE = true;
private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
private static final int HOURS_IN_HALF_DAY = 12;
- private View mHeaderView;
- private TextView mHourView;
- private TextView mMinuteView;
- private TextView mAmPmTextView;
- private RadialTimePickerView mRadialTimePickerView;
- private TextView mSeparatorView;
+ private final View mHeaderView;
+ private final TextView mHourView;
+ private final TextView mMinuteView;
+ private final View mAmPmLayout;
+ private final CheckedTextView mAmLabel;
+ private final CheckedTextView mPmLabel;
+ private final RadialTimePickerView mRadialTimePickerView;
+ private final TextView mSeparatorView;
- private String mAmText;
- private String mPmText;
+ private final String mAmText;
+ private final String mPmText;
+
+ private final float mDisabledAlpha;
private boolean mAllowAutoAdvance;
private int mInitialHourOfDay;
@@ -124,15 +129,18 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
R.layout.time_picker_holo);
- final View mainView = inflater.inflate(layoutResourceId, null);
- mDelegator.addView(mainView);
+ final View mainView = inflater.inflate(layoutResourceId, delegator);
- mHourView = (TextView) mainView.findViewById(R.id.hours);
- mSeparatorView = (TextView) mainView.findViewById(R.id.separator);
- mMinuteView = (TextView) mainView.findViewById(R.id.minutes);
- mAmPmTextView = (TextView) mainView.findViewById(R.id.ampm_label);
+ mHeaderView = mainView.findViewById(R.id.time_header);
+ mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground));
+
+ // Set up hour/minute labels.
+ mHourView = (TextView) mHeaderView.findViewById(R.id.hours);
+ mHourView.setOnClickListener(mClickListener);
+ mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator);
+ mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes);
+ mMinuteView.setOnClickListener(mClickListener);
- // Set up text appearances from style.
final int headerTimeTextAppearance = a.getResourceId(
R.styleable.TimePicker_headerTimeTextAppearance, 0);
if (headerTimeTextAppearance != 0) {
@@ -141,6 +149,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
mMinuteView.setTextAppearance(context, headerTimeTextAppearance);
}
+ // TODO: This can be removed once we support themed color state lists.
final int headerSelectedTextColor = a.getColor(
R.styleable.TimePicker_headerSelectedTextColor,
res.getColor(R.color.timepicker_default_selector_color_material));
@@ -149,17 +158,29 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
mMinuteView.setTextColor(ColorStateList.addFirstIfMissing(mMinuteView.getTextColors(),
R.attr.state_selected, headerSelectedTextColor));
+ // Set up AM/PM labels.
+ mAmPmLayout = mHeaderView.findViewById(R.id.ampm_layout);
+ mAmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.am_label);
+ mAmLabel.setText(amPmStrings[0]);
+ mAmLabel.setOnClickListener(mClickListener);
+ mPmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.pm_label);
+ mPmLabel.setText(amPmStrings[1]);
+ mPmLabel.setOnClickListener(mClickListener);
+
final int headerAmPmTextAppearance = a.getResourceId(
R.styleable.TimePicker_headerAmPmTextAppearance, 0);
if (headerAmPmTextAppearance != 0) {
- mAmPmTextView.setTextAppearance(context, headerAmPmTextAppearance);
+ mAmLabel.setTextAppearance(context, headerAmPmTextAppearance);
+ mPmLabel.setTextAppearance(context, headerAmPmTextAppearance);
}
- mHeaderView = mainView.findViewById(R.id.time_header);
- mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground));
-
a.recycle();
+ // Pull disabled alpha from theme.
+ final TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
+ mDisabledAlpha = outValue.getFloat();
+
mRadialTimePickerView = (RadialTimePickerView) mainView.findViewById(
R.id.radial_picker);
@@ -195,21 +216,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
mHeaderView.setFocusable(true);
mRadialTimePickerView.setOnValueSelectedListener(this);
-
- mHourView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setCurrentItemShowing(HOUR_INDEX, true, true);
- tryVibrate();
- }
- });
- mMinuteView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setCurrentItemShowing(MINUTE_INDEX, true, true);
- tryVibrate();
- }
- });
}
private void updateUI(int index) {
@@ -250,46 +256,31 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
private void updateHeaderAmPm() {
if (mIs24HourView) {
- mAmPmTextView.setVisibility(View.GONE);
+ mAmPmLayout.setVisibility(View.GONE);
} else {
- mAmPmTextView.setVisibility(View.VISIBLE);
- final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
- "hm");
-
+ final String bestDateTimePattern = DateFormat.getBestDateTimePattern(
+ mCurrentLocale, "hm");
boolean amPmOnLeft = bestDateTimePattern.startsWith("a");
if (TextUtils.getLayoutDirectionFromLocale(mCurrentLocale) ==
View.LAYOUT_DIRECTION_RTL) {
amPmOnLeft = !amPmOnLeft;
}
- RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
- mAmPmTextView.getLayoutParams();
+ final ViewGroup.MarginLayoutParams params =
+ (ViewGroup.MarginLayoutParams) mAmPmLayout.getLayoutParams();
if (amPmOnLeft) {
- layoutParams.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */);
- layoutParams.removeRule(RelativeLayout.RIGHT_OF);
- layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.separator);
+ params.leftMargin = 0;
+ params.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */);
} else {
- layoutParams.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */);
- layoutParams.removeRule(RelativeLayout.LEFT_OF);
- layoutParams.addRule(RelativeLayout.RIGHT_OF, R.id.separator);
+ params.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */);
+ params.rightMargin = 0;
}
- updateAmPmDisplay(mInitialHourOfDay < 12 ? AM : PM);
- mAmPmTextView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- tryVibrate();
- int amOrPm = mRadialTimePickerView.getAmOrPm();
- if (amOrPm == AM) {
- amOrPm = PM;
- } else if (amOrPm == PM){
- amOrPm = AM;
- }
- updateAmPmDisplay(amOrPm);
- mRadialTimePickerView.setAmOrPm(amOrPm);
- }
- });
+ mAmPmLayout.setLayoutParams(params);
+ mAmPmLayout.setVisibility(View.VISIBLE);
+
+ updateAmPmLabelStates(mInitialHourOfDay < 12 ? AM : PM);
}
}
@@ -389,7 +380,8 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
public void setEnabled(boolean enabled) {
mHourView.setEnabled(enabled);
mMinuteView.setEnabled(enabled);
- mAmPmTextView.setEnabled(enabled);
+ mAmLabel.setEnabled(enabled);
+ mPmLabel.setEnabled(enabled);
mRadialTimePickerView.setEnabled(enabled);
mIsEnabled = enabled;
}
@@ -596,16 +588,14 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
mDelegator.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
}
- private void updateAmPmDisplay(int amOrPm) {
- if (amOrPm == AM) {
- mAmPmTextView.setText(mAmText);
- mRadialTimePickerView.announceForAccessibility(mAmText);
- } else if (amOrPm == PM){
- mAmPmTextView.setText(mPmText);
- mRadialTimePickerView.announceForAccessibility(mPmText);
- } else {
- mAmPmTextView.setText(mDoublePlaceholderText);
- }
+ private void updateAmPmLabelStates(int amOrPm) {
+ final boolean isAm = amOrPm == AM;
+ mAmLabel.setChecked(isAm);
+ mAmLabel.setAlpha(isAm ? 1 : mDisabledAlpha);
+
+ final boolean isPm = amOrPm == PM;
+ mPmLabel.setChecked(isPm);
+ mPmLabel.setAlpha(isPm ? 1 : mDisabledAlpha);
}
/**
@@ -629,7 +619,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
updateHeaderMinute(newValue);
mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + newValue);
} else if (pickerIndex == AMPM_INDEX) {
- updateAmPmDisplay(newValue);
+ updateAmPmLabelStates(newValue);
} else if (pickerIndex == ENABLE_PICKER_INDEX) {
if (!isTypedTimeFullyLegal()) {
mTypedTimes.clear();
@@ -761,6 +751,11 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
mMinuteView.setSelected(index == MINUTE_INDEX);
}
+ private void setAmOrPm(int amOrPm) {
+ updateAmPmLabelStates(amOrPm);
+ mRadialTimePickerView.setAmOrPm(amOrPm);
+ }
+
/**
* For keyboard mode, processes key events.
*
@@ -929,7 +924,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
updateHeaderHour(hour, true);
updateHeaderMinute(minute);
if (!mIs24HourView) {
- updateAmPmDisplay(hour < 12 ? AM : PM);
+ updateAmPmLabelStates(hour < 12 ? AM : PM);
}
setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true);
onValidationChanged(true);
@@ -947,7 +942,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
mMinuteView.setText(minuteStr);
mMinuteView.setSelected(false);
if (!mIs24HourView) {
- updateAmPmDisplay(values[2]);
+ updateAmPmLabelStates(values[2]);
}
}
}
@@ -1231,6 +1226,33 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im
}
}
+ private final View.OnClickListener mClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ final int amOrPm;
+ switch (v.getId()) {
+ case R.id.am_label:
+ setAmOrPm(AM);
+ break;
+ case R.id.pm_label:
+ setAmOrPm(PM);
+ break;
+ case R.id.hours:
+ setCurrentItemShowing(HOUR_INDEX, true, true);
+ break;
+ case R.id.minutes:
+ setCurrentItemShowing(MINUTE_INDEX, true, true);
+ break;
+ default:
+ // Failed to handle this click, don't vibrate.
+ return;
+ }
+
+ tryVibrate();
+ }
+ };
+
private final View.OnKeyListener mKeyListener = new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
diff --git a/core/res/res/layout/time_header_label.xml b/core/res/res/layout/time_header_label.xml
index 5c97040..84b2b0c 100644
--- a/core/res/res/layout/time_header_label.xml
+++ b/core/res/res/layout/time_header_label.xml
@@ -20,14 +20,13 @@
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center">
+ android:layout_height="match_parent">
<TextView
android:id="@+id/hours"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/separator"
- android:layout_alignBaseline="@+id/separator" />
+ android:layout_centerVertical="true" />
<TextView
android:id="@+id/separator"
android:layout_width="wrap_content"
@@ -41,14 +40,31 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/separator"
- android:layout_alignBaseline="@+id/separator" />
- <TextView
- android:id="@+id/ampm_label"
+ android:layout_centerVertical="true" />
+ <LinearLayout
+ android:id="@+id/ampm_layout"
+ android:layout_alignBaseline="@+id/minutes"
+ android:layout_toEndOf="@+id/separator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingLeft="@dimen/timepicker_ampm_left_padding"
- android:paddingRight="@dimen/timepicker_ampm_left_padding"
- android:layout_toRightOf="@+id/separator"
- android:layout_alignBaseline="@+id/separator" />
+ android:baselineAlignedChildIndex="1"
+ android:orientation="vertical">
+ <CheckedTextView
+ android:id="@+id/am_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingTop="@dimen/timepicker_ampm_vertical_padding"
+ android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingBottom="@dimen/timepicker_am_bottom_padding" />
+ <CheckedTextView
+ android:id="@+id/pm_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingTop="@dimen/timepicker_pm_top_padding"
+ android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingBottom="@dimen/timepicker_ampm_vertical_padding" />
+ </LinearLayout>
</RelativeLayout>
</FrameLayout>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 26d3133..71f66ba 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -367,12 +367,15 @@
<dimen name="timepicker_time_label_size">60sp</dimen>
<dimen name="timepicker_extra_time_label_margin">-30dp</dimen>
<dimen name="timepicker_ampm_label_size">16sp</dimen>
- <dimen name="timepicker_ampm_left_padding">6dip</dimen>
- <dimen name="timepicker_separator_padding">4dip</dimen>
- <dimen name="timepicker_header_height">96dip</dimen>
- <dimen name="timepicker_minimum_margin_sides">48dip</dimen>
- <dimen name="timepicker_minimum_margin_top_bottom">24dip</dimen>
- <dimen name="timepicker_radial_picker_dimen">270dip</dimen>
+ <dimen name="timepicker_ampm_horizontal_padding">12dp</dimen>
+ <dimen name="timepicker_ampm_vertical_padding">16dp</dimen>
+ <dimen name="timepicker_am_bottom_padding">1dp</dimen>
+ <dimen name="timepicker_pm_top_padding">2dp</dimen>
+ <dimen name="timepicker_separator_padding">4dp</dimen>
+ <dimen name="timepicker_header_height">96dp</dimen>
+ <dimen name="timepicker_minimum_margin_sides">48dp</dimen>
+ <dimen name="timepicker_minimum_margin_top_bottom">24dp</dimen>
+ <dimen name="timepicker_radial_picker_dimen">270dp</dimen>
<!-- Used by SimpleMonthView -->
<dimen name="datepicker_day_number_size">12sp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d9129fe..71f0642 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1936,7 +1936,9 @@
<java-symbol type="id" name="time_header" />
<java-symbol type="id" name="hours" />
<java-symbol type="id" name="minutes" />
- <java-symbol type="id" name="ampm_label" />
+ <java-symbol type="id" name="ampm_layout" />
+ <java-symbol type="id" name="am_label" />
+ <java-symbol type="id" name="pm_label" />
<java-symbol type="id" name="radial_picker" />
<java-symbol type="id" name="separator" />
<java-symbol type="id" name="date_picker_header" />