diff options
author | Alan Viverette <alanv@google.com> | 2015-02-20 10:51:33 -0800 |
---|---|---|
committer | Alan Viverette <alanv@google.com> | 2015-02-20 10:51:33 -0800 |
commit | adbc95f015aed3c6d67bc05507cafa2148cc5d94 (patch) | |
tree | 2ed23cf69b53df878759a6944e8034f81b28dde8 | |
parent | c20f54aff64a5b29003968249906c9443208a845 (diff) | |
download | frameworks_base-adbc95f015aed3c6d67bc05507cafa2148cc5d94.zip frameworks_base-adbc95f015aed3c6d67bc05507cafa2148cc5d94.tar.gz frameworks_base-adbc95f015aed3c6d67bc05507cafa2148cc5d94.tar.bz2 |
Update time picker to match latest Material spec
Also removes saveLayerAlpha() call from radial time picker's disabled
drawing path.
Bug: 19431361
Change-Id: I18641bb9544107bb8704fc43d0dd6c5b18ff99ce
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | api/system-current.txt | 1 | ||||
-rw-r--r-- | core/java/android/widget/RadialTimePickerView.java | 296 | ||||
-rw-r--r-- | core/java/android/widget/RelativeLayout.java | 12 | ||||
-rw-r--r-- | core/java/android/widget/TimePickerClockDelegate.java | 30 | ||||
-rw-r--r-- | core/res/res/layout/time_header_label.xml | 106 | ||||
-rw-r--r-- | core/res/res/layout/time_picker_holo.xml | 2 | ||||
-rw-r--r-- | core/res/res/values/attrs.xml | 2 | ||||
-rw-r--r-- | core/res/res/values/dimens.xml | 25 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 1 | ||||
-rw-r--r-- | core/res/res/values/styles_material.xml | 3 | ||||
-rwxr-xr-x | core/res/res/values/symbols.xml | 16 |
12 files changed, 209 insertions, 286 deletions
diff --git a/api/current.txt b/api/current.txt index cd74fe5..e6379e2 100644 --- a/api/current.txt +++ b/api/current.txt @@ -886,6 +886,7 @@ package android { field public static final int numColumns = 16843032; // 0x1010118 field public static final int numStars = 16843076; // 0x1010144 field public static final int numbersBackgroundColor = 16843938; // 0x10104a2 + field public static final int numbersInnerTextColor = 16843999; // 0x10104df field public static final int numbersSelectorColor = 16843939; // 0x10104a3 field public static final int numbersTextColor = 16843937; // 0x10104a1 field public static final deprecated int numeric = 16843109; // 0x1010165 diff --git a/api/system-current.txt b/api/system-current.txt index b016a96..33e1178 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -958,6 +958,7 @@ package android { field public static final int numColumns = 16843032; // 0x1010118 field public static final int numStars = 16843076; // 0x1010144 field public static final int numbersBackgroundColor = 16843938; // 0x10104a2 + field public static final int numbersInnerTextColor = 16843999; // 0x10104df field public static final int numbersSelectorColor = 16843939; // 0x10104a3 field public static final int numbersTextColor = 16843937; // 0x10104a1 field public static final deprecated int numeric = 16843109; // 0x1010165 diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java index 4b061d3..dc4d932 100644 --- a/core/java/android/widget/RadialTimePickerView.java +++ b/core/java/android/widget/RadialTimePickerView.java @@ -43,7 +43,6 @@ import android.util.TypedValue; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -63,12 +62,6 @@ import java.util.Locale; public class RadialTimePickerView extends View { private static final String TAG = "RadialTimePickerView"; - private static final boolean DEBUG = false; - - private static final int DEBUG_COLOR = 0x20FF0000; - private static final int DEBUG_TEXT_COLOR = 0x60FF0000; - private static final int DEBUG_STROKE_WIDTH = 2; - private static final int HOURS = 0; private static final int MINUTES = 1; private static final int HOURS_INNER = 2; @@ -93,8 +86,6 @@ public class RadialTimePickerView extends View { private static final int[] HOURS_NUMBERS_24 = {0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; private static final int[] MINUTES_NUMBERS = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55}; - private static final int CENTER_RADIUS = 2; - private static final int FADE_OUT_DURATION = 500; private static final int FADE_IN_DURATION = 500; @@ -135,11 +126,12 @@ public class RadialTimePickerView extends View { private final IntHolder[][] mAlphaSelector = new IntHolder[2][3]; private final Paint mPaintBackground = new Paint(); - private final Paint mPaintDebug = new Paint(); private final Typeface mTypeface; - private final float[] mTextSize = new float[2]; + private final ColorStateList[] mTextColor = new ColorStateList[3]; + private final int[] mTextSize = new int[3]; + private final int[] mTextInset = new int[3]; private final float[][] mOuterTextX = new float[2][12]; private final float[][] mOuterTextY = new float[2][12]; @@ -147,22 +139,14 @@ public class RadialTimePickerView extends View { private final float[] mInnerTextX = new float[12]; private final float[] mInnerTextY = new float[12]; - private final float[] mNumbersRadiusMultiplier = new float[3]; - - private final float[] mTextSizeMultiplier = new float[3]; - private final int[] mLineLength = new int[3]; - private final int[] mSelectionRadius = new int[3]; - private final float mSelectionRadiusMultiplier; private final int[] mSelectionDegrees = new int[3]; - private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<Animator>(); - private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<Animator>(); + private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<>(); + private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<>(); private final RadialPickerTouchHelper mTouchHelper; - private ColorStateList mNumbersTextColor; - private boolean mIs24HourMode; private boolean mShowHours; @@ -172,9 +156,13 @@ public class RadialTimePickerView extends View { */ private boolean mIsOnInnerCircle; - private float mXCenter; - private float mYCenter; - private float mCircleRadius; + private int mSelectorRadius; + private int mSelectorDotRadius; + private int mCenterDotRadius; + + private int mXCenter; + private int mYCenter; + private int mCircleRadius; private int mMinHypotenuseForInnerNumber; private int mMaxHypotenuseForOuterNumber; @@ -186,7 +174,8 @@ public class RadialTimePickerView extends View { private AnimatorSet mTransition; private int mAmOrPm; - private int mDisabledAlpha; + + private float mDisabledAlpha; private OnValueSelectedListener mListener; @@ -313,7 +302,7 @@ public class RadialTimePickerView extends View { // Pull disabled alpha from theme. final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); - mDisabledAlpha = (int) (outValue.getFloat() * 255 + 0.5f); + mDisabledAlpha = outValue.getFloat(); // process style attributes final Resources res = getResources(); @@ -332,8 +321,9 @@ public class RadialTimePickerView extends View { } } - mNumbersTextColor = a.getColorStateList( - R.styleable.TimePicker_numbersTextColor); + mTextColor[HOURS] = a.getColorStateList(R.styleable.TimePicker_numbersTextColor); + mTextColor[HOURS_INNER] = a.getColorStateList(R.styleable.TimePicker_numbersInnerTextColor); + mTextColor[MINUTES] = mTextColor[HOURS]; mPaint[HOURS] = new Paint(); mPaint[HOURS].setAntiAlias(true); @@ -351,8 +341,8 @@ public class RadialTimePickerView extends View { mPaintCenter.setColor(selectorActivatedColor); mPaintCenter.setAntiAlias(true); - final int textActivatedColor = mNumbersTextColor.getColorForState( - StateSet.get(StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_ACTIVATED), 0); + final int[] activatedStateSet = StateSet.get( + StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_ACTIVATED); mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true); @@ -360,7 +350,8 @@ public class RadialTimePickerView extends View { mPaintSelector[HOURS][SELECTOR_DOT] = new Paint(); mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true); - mColorSelector[HOURS][SELECTOR_DOT] = textActivatedColor; + mColorSelector[HOURS][SELECTOR_DOT] = + mTextColor[HOURS].getColorForState(activatedStateSet, 0); mPaintSelector[HOURS][SELECTOR_LINE] = new Paint(); mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true); @@ -373,7 +364,8 @@ public class RadialTimePickerView extends View { mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint(); mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true); - mColorSelector[MINUTES][SELECTOR_DOT] = textActivatedColor; + mColorSelector[MINUTES][SELECTOR_DOT] = + mTextColor[MINUTES].getColorForState(activatedStateSet, 0); mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true); @@ -384,13 +376,17 @@ public class RadialTimePickerView extends View { context.getColor(R.color.timepicker_default_numbers_background_color_material))); mPaintBackground.setAntiAlias(true); - if (DEBUG) { - mPaintDebug.setColor(DEBUG_COLOR); - mPaintDebug.setAntiAlias(true); - mPaintDebug.setStrokeWidth(DEBUG_STROKE_WIDTH); - mPaintDebug.setStyle(Paint.Style.STROKE); - mPaintDebug.setTextAlign(Paint.Align.CENTER); - } + mSelectorRadius = res.getDimensionPixelSize(R.dimen.timepicker_selector_radius); + mSelectorDotRadius = res.getDimensionPixelSize(R.dimen.timepicker_selector_dot_radius); + mCenterDotRadius = res.getDimensionPixelSize(R.dimen.timepicker_center_dot_radius); + + mTextSize[HOURS] = res.getDimensionPixelSize(R.dimen.timepicker_text_size_normal); + mTextSize[MINUTES] = res.getDimensionPixelSize(R.dimen.timepicker_text_size_normal); + mTextSize[HOURS_INNER] = res.getDimensionPixelSize(R.dimen.timepicker_text_size_inner); + + mTextInset[HOURS] = res.getDimensionPixelSize(R.dimen.timepicker_text_inset_normal); + mTextInset[MINUTES] = res.getDimensionPixelSize(R.dimen.timepicker_text_inset_normal); + mTextInset[HOURS_INNER] = res.getDimensionPixelSize(R.dimen.timepicker_text_inset_inner); mShowHours = true; mIs24HourMode = false; @@ -407,8 +403,6 @@ public class RadialTimePickerView extends View { initHoursAndMinutesText(); initData(); - mSelectionRadiusMultiplier = res.getFloat(R.dimen.timepicker_selection_radius_multiplier); - a.recycle(); // Initial values @@ -621,30 +615,6 @@ public class RadialTimePickerView extends View { mOuterTextMinutes = mMinutesTexts; - final Resources res = getResources(); - - if (mIs24HourMode) { - mNumbersRadiusMultiplier[HOURS] = res.getFloat( - R.dimen.timepicker_numbers_radius_multiplier_outer); - mTextSizeMultiplier[HOURS] = res.getFloat( - R.dimen.timepicker_text_size_multiplier_outer); - - mNumbersRadiusMultiplier[HOURS_INNER] = res.getFloat( - R.dimen.timepicker_numbers_radius_multiplier_inner); - mTextSizeMultiplier[HOURS_INNER] = res.getFloat( - R.dimen.timepicker_text_size_multiplier_inner); - } else { - mNumbersRadiusMultiplier[HOURS] = res.getFloat( - R.dimen.timepicker_numbers_radius_multiplier_normal); - mTextSizeMultiplier[HOURS] = res.getFloat( - R.dimen.timepicker_text_size_multiplier_normal); - } - - mNumbersRadiusMultiplier[MINUTES] = res.getFloat( - R.dimen.timepicker_numbers_radius_multiplier_normal); - mTextSizeMultiplier[MINUTES] = res.getFloat( - R.dimen.timepicker_text_size_multiplier_normal); - final int hoursAlpha = mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT; mAlpha[HOURS].setValue(hoursAlpha); mAlphaSelector[HOURS][SELECTOR_CIRCLE].setValue(hoursAlpha); @@ -668,96 +638,78 @@ public class RadialTimePickerView extends View { mYCenter = getHeight() / 2; mCircleRadius = Math.min(mXCenter, mYCenter); - mMinHypotenuseForInnerNumber = (int) (mCircleRadius - * mNumbersRadiusMultiplier[HOURS_INNER]) - mSelectionRadius[HOURS]; - mMaxHypotenuseForOuterNumber = (int) (mCircleRadius - * mNumbersRadiusMultiplier[HOURS]) + mSelectionRadius[HOURS]; - mHalfwayHypotenusePoint = (int) (mCircleRadius - * ((mNumbersRadiusMultiplier[HOURS] + mNumbersRadiusMultiplier[HOURS_INNER]) / 2)); - - mTextSize[HOURS] = mCircleRadius * mTextSizeMultiplier[HOURS]; - mTextSize[MINUTES] = mCircleRadius * mTextSizeMultiplier[MINUTES]; - - if (mIs24HourMode) { - mTextSize[HOURS_INNER] = mCircleRadius * mTextSizeMultiplier[HOURS_INNER]; - } + mMinHypotenuseForInnerNumber = mCircleRadius - mTextInset[HOURS_INNER] - mSelectorRadius; + mMaxHypotenuseForOuterNumber = mCircleRadius - mTextInset[HOURS] - mSelectorRadius; + mHalfwayHypotenusePoint = mCircleRadius - (mTextInset[HOURS] + mTextInset[HOURS_INNER]) / 2; calculatePositionsHours(); calculatePositionsMinutes(); - mSelectionRadius[HOURS] = (int) (mCircleRadius * mSelectionRadiusMultiplier); - mSelectionRadius[HOURS_INNER] = mSelectionRadius[HOURS]; - mSelectionRadius[MINUTES] = (int) (mCircleRadius * mSelectionRadiusMultiplier); - mTouchHelper.invalidateRoot(); } @Override public void onDraw(Canvas canvas) { - if (!mInputEnabled) { - canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), mDisabledAlpha); - } else { - canvas.save(); - } + final float alphaMod = mInputEnabled ? 1 : mDisabledAlpha; drawCircleBackground(canvas); + drawHours(canvas, alphaMod); + drawMinutes(canvas, alphaMod); + drawCenter(canvas, alphaMod); + } - final int hoursAlpha = mAlpha[HOURS].getValue(); + private void drawCircleBackground(Canvas canvas) { + canvas.drawCircle(mXCenter, mYCenter, mCircleRadius, mPaintBackground); + } + + private void drawHours(Canvas canvas, float alphaMod) { + final int hoursAlpha = (int) (mAlpha[HOURS].getValue() * alphaMod + 0.5f); if (hoursAlpha > 0) { // Draw the hour selector under the elements. - drawSelector(canvas, mIsOnInnerCircle ? HOURS_INNER : HOURS, null); + drawSelector(canvas, mIsOnInnerCircle ? HOURS_INNER : HOURS, null, alphaMod); // Draw outer hours. - drawTextElements(canvas, mTextSize[HOURS], mTypeface, mOuterTextHours, - mOuterTextX[HOURS], mOuterTextY[HOURS], mPaint[HOURS], hoursAlpha, - !mIsOnInnerCircle, mSelectionDegrees[HOURS], false); + drawTextElements(canvas, mTextSize[HOURS], mTypeface, mTextColor[HOURS], + mOuterTextHours, mOuterTextX[HOURS], mOuterTextY[HOURS], mPaint[HOURS], + hoursAlpha, !mIsOnInnerCircle, mSelectionDegrees[HOURS], false); // Draw inner hours (12-23) for 24-hour time. if (mIs24HourMode && mInnerTextHours != null) { - drawTextElements(canvas, mTextSize[HOURS_INNER], mTypeface, mInnerTextHours, - mInnerTextX, mInnerTextY, mPaint[HOURS], hoursAlpha, + drawTextElements(canvas, mTextSize[HOURS_INNER], mTypeface, mTextColor[HOURS_INNER], + mInnerTextHours, mInnerTextX, mInnerTextY, mPaint[HOURS], hoursAlpha, mIsOnInnerCircle, mSelectionDegrees[HOURS], false); } } + } - final int minutesAlpha = mAlpha[MINUTES].getValue(); + private void drawMinutes(Canvas canvas, float alphaMod) { + final int minutesAlpha = (int) (mAlpha[MINUTES].getValue() * alphaMod + 0.5f); if (minutesAlpha > 0) { - drawSelector(canvas, MINUTES, mSelectorPath); + drawSelector(canvas, MINUTES, mSelectorPath, alphaMod); // Exclude the selector region, then draw minutes with no // activated states. canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.clipPath(mSelectorPath, Region.Op.DIFFERENCE); - drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes, - mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES], minutesAlpha, - false, 0, false); + drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mTextColor[MINUTES], + mOuterTextMinutes, mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES], + minutesAlpha, false, 0, false); canvas.restore(); // Intersect the selector region, then draw minutes with only // activated states. canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.clipPath(mSelectorPath, Region.Op.INTERSECT); - drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes, - mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES], minutesAlpha, - true, mSelectionDegrees[MINUTES], true); + drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mTextColor[MINUTES], + mOuterTextMinutes, mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES], + minutesAlpha, true, mSelectionDegrees[MINUTES], true); canvas.restore(); } - - drawCenter(canvas); - - if (DEBUG) { - drawDebug(canvas); - } - - canvas.restore(); } - private void drawCircleBackground(Canvas canvas) { - canvas.drawCircle(mXCenter, mYCenter, mCircleRadius, mPaintBackground); - } - - private void drawCenter(Canvas canvas) { - canvas.drawCircle(mXCenter, mYCenter, CENTER_RADIUS, mPaintCenter); + private void drawCenter(Canvas canvas, float alphaMod) { + mPaintCenter.setAlpha((int) (255 * alphaMod + 0.5f)); + canvas.drawCircle(mXCenter, mYCenter, mCenterDotRadius, mPaintCenter); } private int getMultipliedAlpha(int argb, int alpha) { @@ -766,9 +718,9 @@ public class RadialTimePickerView extends View { private final Path mSelectorPath = new Path(); - private void drawSelector(Canvas canvas, int index, Path selectorPath) { + private void drawSelector(Canvas canvas, int index, Path selectorPath, float alphaMod) { // Calculate the current radius at which to place the selection circle. - mLineLength[index] = (int) (mCircleRadius * mNumbersRadiusMultiplier[index]); + mLineLength[index] = mCircleRadius - mTextInset[index]; final double selectionRadians = Math.toRadians(mSelectionDegrees[index]); @@ -781,16 +733,16 @@ public class RadialTimePickerView extends View { // Draw the selection circle color = mColorSelector[index % 2][SELECTOR_CIRCLE]; - alpha = mAlphaSelector[index % 2][SELECTOR_CIRCLE].getValue(); + alpha = (int) (mAlphaSelector[index % 2][SELECTOR_CIRCLE].getValue() * alphaMod + 0.5f); paint = mPaintSelector[index % 2][SELECTOR_CIRCLE]; paint.setColor(color); paint.setAlpha(getMultipliedAlpha(color, alpha)); - canvas.drawCircle(pointX, pointY, mSelectionRadius[index], paint); + canvas.drawCircle(pointX, pointY, mSelectorRadius, paint); // If needed, set up the clip path for later. if (selectorPath != null) { mSelectorPath.reset(); - mSelectorPath.addCircle(pointX, pointY, mSelectionRadius[index], Path.Direction.CCW); + mSelectorPath.addCircle(pointX, pointY, mSelectorRadius, Path.Direction.CCW); } // Draw the dot if needed. @@ -798,80 +750,35 @@ public class RadialTimePickerView extends View { if (shouldDrawDot) { // We're not on a direct tick color = mColorSelector[index % 2][SELECTOR_DOT]; - alpha = mAlphaSelector[index % 2][SELECTOR_DOT].getValue(); + alpha = (int) (mAlphaSelector[index % 2][SELECTOR_DOT].getValue() * alphaMod + 0.5f); paint = mPaintSelector[index % 2][SELECTOR_DOT]; paint.setColor(color); paint.setAlpha(getMultipliedAlpha(color, alpha)); - canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 0.125f), paint); + canvas.drawCircle(pointX, pointY, mSelectorDotRadius, paint); } - // Shorten the line to only go to the edge of the selection circle. - final int lineLength = mLineLength[index] - mSelectionRadius[index]; - pointX = mXCenter + (int) (lineLength * Math.sin(selectionRadians)); - pointY = mYCenter - (int) (lineLength * Math.cos(selectionRadians)); + // Shorten the line to only go from the edge of the center dot to the + // edge of the selection circle. + final double sin = Math.sin(selectionRadians); + final double cos = Math.cos(selectionRadians); + final int lineLength = mLineLength[index] - mSelectorRadius; + final int centerX = mXCenter + (int) (mCenterDotRadius * sin); + final int centerY = mYCenter - (int) (mCenterDotRadius * cos); + pointX = centerX + (int) (lineLength * sin); + pointY = centerY - (int) (lineLength * cos); // Draw the line color = mColorSelector[index % 2][SELECTOR_LINE]; - alpha = mAlphaSelector[index % 2][SELECTOR_LINE].getValue(); + alpha = (int) (mAlphaSelector[index % 2][SELECTOR_LINE].getValue() * alphaMod + 0.5f); paint = mPaintSelector[index % 2][SELECTOR_LINE]; paint.setColor(color); paint.setAlpha(getMultipliedAlpha(color, alpha)); canvas.drawLine(mXCenter, mYCenter, pointX, pointY, paint); } - private void drawDebug(Canvas canvas) { - // Draw outer numbers circle - final float outerRadius = mCircleRadius * mNumbersRadiusMultiplier[HOURS]; - canvas.drawCircle(mXCenter, mYCenter, outerRadius, mPaintDebug); - - // Draw inner numbers circle - final float innerRadius = mCircleRadius * mNumbersRadiusMultiplier[HOURS_INNER]; - canvas.drawCircle(mXCenter, mYCenter, innerRadius, mPaintDebug); - - // Draw outer background circle - canvas.drawCircle(mXCenter, mYCenter, mCircleRadius, mPaintDebug); - - // Draw outer rectangle for circles - float left = mXCenter - outerRadius; - float top = mYCenter - outerRadius; - float right = mXCenter + outerRadius; - float bottom = mYCenter + outerRadius; - canvas.drawRect(left, top, right, bottom, mPaintDebug); - - // Draw outer rectangle for background - left = mXCenter - mCircleRadius; - top = mYCenter - mCircleRadius; - right = mXCenter + mCircleRadius; - bottom = mYCenter + mCircleRadius; - canvas.drawRect(left, top, right, bottom, mPaintDebug); - - // Draw outer view rectangle - canvas.drawRect(0, 0, getWidth(), getHeight(), mPaintDebug); - - // Draw selected time - final String selected = String.format("%02d:%02d", getCurrentHour(), getCurrentMinute()); - - ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - TextView tv = new TextView(getContext()); - tv.setLayoutParams(lp); - tv.setText(selected); - tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - Paint paint = tv.getPaint(); - paint.setColor(DEBUG_TEXT_COLOR); - - final int width = tv.getMeasuredWidth(); - - float height = paint.descent() - paint.ascent(); - float x = mXCenter - width / 2; - float y = mYCenter + 1.5f * height; - - canvas.drawText(selected, x, y, paint); - } - private void calculatePositionsHours() { // Calculate the text positions - final float numbersRadius = mCircleRadius * mNumbersRadiusMultiplier[HOURS]; + final float numbersRadius = mCircleRadius - mTextInset[HOURS]; // Calculate the positions for the 12 numbers in the main circle. calculatePositions(mPaint[HOURS], numbersRadius, mXCenter, mYCenter, @@ -879,9 +786,7 @@ public class RadialTimePickerView extends View { // If we have an inner circle, calculate those positions too. if (mIs24HourMode) { - final float innerNumbersRadius = mCircleRadius - * mNumbersRadiusMultiplier[HOURS_INNER]; - + final int innerNumbersRadius = mCircleRadius - mTextInset[HOURS_INNER]; calculatePositions(mPaint[HOURS], innerNumbersRadius, mXCenter, mYCenter, mTextSize[HOURS_INNER], mInnerTextX, mInnerTextY); } @@ -889,7 +794,7 @@ public class RadialTimePickerView extends View { private void calculatePositionsMinutes() { // Calculate the text positions - final float numbersRadius = mCircleRadius * mNumbersRadiusMultiplier[MINUTES]; + final float numbersRadius = mCircleRadius - mTextInset[MINUTES]; // Calculate the positions for the 12 numbers in the main circle. calculatePositions(mPaint[MINUTES], numbersRadius, mXCenter, mYCenter, @@ -916,9 +821,9 @@ public class RadialTimePickerView extends View { /** * Draw the 12 text values at the positions specified by the textGrid parameters. */ - private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, String[] texts, - float[] textX, float[] textY, Paint paint, int alpha, boolean showActivated, - int activatedDegrees, boolean activatedOnly) { + private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, + ColorStateList textColor, String[] texts, float[] textX, float[] textY, Paint paint, + int alpha, boolean showActivated, int activatedDegrees, boolean activatedOnly) { paint.setTextSize(textSize); paint.setTypeface(typeface); @@ -935,7 +840,7 @@ public class RadialTimePickerView extends View { final int stateMask = StateSet.VIEW_STATE_ENABLED | (showActivated && activated ? StateSet.VIEW_STATE_ACTIVATED : 0); - final int color = mNumbersTextColor.getColorForState(StateSet.get(stateMask), 0); + final int color = textColor.getColorForState(StateSet.get(stateMask), 0); paint.setColor(color); paint.setAlpha(getMultipliedAlpha(color, alpha)); @@ -1058,10 +963,9 @@ public class RadialTimePickerView extends View { } } else { final int index = (mShowHours) ? HOURS : MINUTES; - final float length = (mCircleRadius * mNumbersRadiusMultiplier[index]); + final float length = (mCircleRadius - mTextInset[index]); final int distanceToNumber = (int) (hypotenuse - length); - final int maxAllowedDistance = - (int) (mCircleRadius * (1 - mNumbersRadiusMultiplier[index])); + final int maxAllowedDistance = mTextInset[index]; if (distanceToNumber < -maxAllowedDistance || (constrainOutside && distanceToNumber > maxAllowedDistance)) { return -1; @@ -1431,18 +1335,18 @@ public class RadialTimePickerView extends View { if (type == TYPE_HOUR) { final boolean innerCircle = mIs24HourMode && value > 0 && value <= 12; if (innerCircle) { - centerRadius = mCircleRadius * mNumbersRadiusMultiplier[HOURS_INNER]; - radius = mSelectionRadius[HOURS_INNER]; + centerRadius = mCircleRadius - mTextInset[HOURS_INNER]; + radius = mSelectorRadius; } else { - centerRadius = mCircleRadius * mNumbersRadiusMultiplier[HOURS]; - radius = mSelectionRadius[HOURS]; + centerRadius = mCircleRadius - mTextInset[HOURS]; + radius = mSelectorRadius; } degrees = getDegreesForHour(value); } else if (type == TYPE_MINUTE) { - centerRadius = mCircleRadius * mNumbersRadiusMultiplier[MINUTES]; + centerRadius = mCircleRadius - mTextInset[MINUTES]; degrees = getDegreesForMinute(value); - radius = mSelectionRadius[MINUTES]; + radius = mSelectorRadius; } else { // This should never happen. centerRadius = 0; diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 89b1d54..fef56b8 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -617,15 +617,17 @@ public class RelativeLayout extends ViewGroup { } } - // Use the bottom-most view as the baseline. + // Use the bottom-most laid out view as the baseline. View baselineView = null; int baseline = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); - final int childBaseline = child.getBaseline(); - if (childBaseline >= baseline) { - baselineView = child; - baseline = childBaseline; + if (child.getVisibility() != GONE) { + final int childBaseline = child.getBaseline(); + if (childBaseline >= baseline) { + baselineView = child; + baseline = childBaseline; + } } } mBaselineView = baselineView; diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java index 05c7a5f..ed052af 100644 --- a/core/java/android/widget/TimePickerClockDelegate.java +++ b/core/java/android/widget/TimePickerClockDelegate.java @@ -91,6 +91,7 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl private int mInitialHourOfDay; private int mInitialMinute; private boolean mIs24HourView; + private boolean mIsAmPmAtStart; // For hardware IME input. private char mPlaceholderText; @@ -284,24 +285,37 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl } private void updateHeaderAmPm() { + if (mIs24HourView) { mAmPmLayout.setVisibility(View.GONE); } else { // Ensure that AM/PM layout is in the correct position. final String dateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, "hm"); - final boolean amPmAtStart = dateTimePattern.startsWith("a"); - final ViewGroup parent = (ViewGroup) mAmPmLayout.getParent(); - final int targetIndex = amPmAtStart ? 0 : parent.getChildCount() - 1; - final int currentIndex = parent.indexOfChild(mAmPmLayout); - if (targetIndex != currentIndex) { - parent.removeView(mAmPmLayout); - parent.addView(mAmPmLayout, targetIndex); - } + final boolean isAmPmAtStart = dateTimePattern.startsWith("a"); + setAmPmAtStart(isAmPmAtStart); updateAmPmLabelStates(mInitialHourOfDay < 12 ? AM : PM); } } + private void setAmPmAtStart(boolean isAmPmAtStart) { + if (mIsAmPmAtStart != isAmPmAtStart) { + mIsAmPmAtStart = isAmPmAtStart; + + final RelativeLayout.LayoutParams params = + (RelativeLayout.LayoutParams) mAmPmLayout.getLayoutParams(); + if (isAmPmAtStart) { + params.removeRule(RelativeLayout.RIGHT_OF); + params.addRule(RelativeLayout.LEFT_OF, mHourView.getId()); + } else { + params.removeRule(RelativeLayout.LEFT_OF); + params.addRule(RelativeLayout.RIGHT_OF, mMinuteView.getId()); + } + + mAmPmLayout.setLayoutParams(params); + } + } + /** * Set the current hour. */ diff --git a/core/res/res/layout/time_header_label.xml b/core/res/res/layout/time_header_label.xml index 6ccde33..46e7c54 100644 --- a/core/res/res/layout/time_header_label.xml +++ b/core/res/res/layout/time_header_label.xml @@ -14,69 +14,71 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/time_header" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="@dimen/timepicker_separator_padding" - android:gravity="center"> + android:gravity="center" + android:orientation="horizontal" + android:padding="@dimen/timepicker_separator_padding"> - <LinearLayout + <!-- The hour should always be to the left of the separator, + regardless of the current locale's layout direction. --> + <TextView + android:id="@+id/hours" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center" - android:gravity="bottom" - android:orientation="horizontal" - android:layoutDirection="ltr"> + android:layout_toLeftOf="@+id/separator" + android:layout_alignBaseline="@+id/separator" + android:gravity="right" /> - <TextView - android:id="@+id/hours" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="right" - android:layoutDirection="locale" /> + <TextView + android:id="@+id/separator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/timepicker_separator_padding" + android:layout_marginRight="@dimen/timepicker_separator_padding" + android:layout_centerInParent="true" + android:importantForAccessibility="no" /> - <TextView - android:id="@+id/separator" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/timepicker_separator_padding" - android:layout_marginRight="@dimen/timepicker_separator_padding" - android:importantForAccessibility="no" - android:layoutDirection="locale" /> + <!-- The minutes should always be to the left of the separator, + regardless of the current locale's layout direction. --> + <TextView + android:id="@+id/minutes" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toRightOf="@+id/separator" + android:layout_alignBaseline="@+id/separator" + android:gravity="left" /> - <TextView - android:id="@+id/minutes" + <!-- The layout alignment of this view will switch between toRightOf + @id/minutes and toLeftOf @id/hours depending on the locale. --> + <LinearLayout + android:id="@+id/ampm_layout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toRightOf="@+id/minutes" + android:layout_alignBaseline="@+id/minutes" + android:orientation="vertical" + android:baselineAlignedChildIndex="1"> + <CheckedTextView + android:id="@+id/am_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:gravity="left" - android:layoutDirection="locale" /> - - <LinearLayout - android:id="@+id/ampm_layout" + android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" + android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" + android:paddingTop="@dimen/timepicker_ampm_vertical_padding" + android:lines="1" + android:ellipsize="none" /> + <CheckedTextView + android:id="@+id/pm_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="vertical" - android:baselineAlignedChildIndex="1" - android:layoutDirection="locale"> - <CheckedTextView - android:id="@+id/am_label" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" - android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" - android:paddingTop="@dimen/timepicker_ampm_vertical_padding" - android:lines="1" - android:ellipsize="none" /> - <CheckedTextView - android:id="@+id/pm_label" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" - android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" - android:paddingTop="@dimen/timepicker_pm_top_padding" - android:lines="1" - android:ellipsize="none" /> - </LinearLayout> + android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" + android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" + android:paddingTop="@dimen/timepicker_pm_top_padding" + android:lines="1" + android:ellipsize="none" /> </LinearLayout> -</FrameLayout> +</RelativeLayout> diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml index 7a9f90a..cb25dbe 100644 --- a/core/res/res/layout/time_picker_holo.xml +++ b/core/res/res/layout/time_picker_holo.xml @@ -28,7 +28,7 @@ android:layout_gravity="center" /> <android.widget.RadialTimePickerView android:id="@+id/radial_picker" - android:layout_width="@dimen/timepicker_radial_picker_dimen" + android:layout_width="wrap_content" android:layout_height="@dimen/timepicker_radial_picker_dimen" android:layout_gravity="center" android:layout_marginTop="?attr/dialogPreferredPadding" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index bc20378..6bb61a2 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4778,6 +4778,8 @@ <attr name="headerBackground" /> <!-- The color for the hours/minutes numbers. --> <attr name="numbersTextColor" format="color" /> + <!-- The color for the inner hours numbers used in 24-hour mode. --> + <attr name="numbersInnerTextColor" format="color" /> <!-- The background color for the hours/minutes numbers. --> <attr name="numbersBackgroundColor" format="color" /> <!-- The color for the AM/PM selectors. --> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index bec224e..c418dc3 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -357,26 +357,23 @@ <dimen name="subtitle_outline_width">2dp</dimen> <!-- New TimePicker dimensions. --> - <item name="timepicker_selection_radius_multiplier" format="float" type="dimen">0.16</item> - <item name="timepicker_numbers_radius_multiplier_normal" format="float" type="dimen">0.81</item> - <item name="timepicker_numbers_radius_multiplier_inner" format="float" type="dimen">0.60</item> - <item name="timepicker_numbers_radius_multiplier_outer" format="float" type="dimen">0.83</item> - <item name="timepicker_text_size_multiplier_normal" format="float" type="dimen">0.17</item> - <item name="timepicker_text_size_multiplier_inner" format="float" type="dimen">0.14</item> - <item name="timepicker_text_size_multiplier_outer" format="float" type="dimen">0.11</item> - <item name="timepicker_transition_mid_radius_multiplier" format="float" type="dimen">0.95</item> - <item name="timepicker_transition_end_radius_multiplier" format="float" type="dimen">1.3</item> - - <dimen name="timepicker_time_label_size">60sp</dimen> - <dimen name="timepicker_extra_time_label_margin">-30dp</dimen> + <dimen name="timepicker_selector_radius">24dp</dimen> + <dimen name="timepicker_center_dot_radius">4dp</dimen> + <dimen name="timepicker_selector_dot_radius">4dp</dimen> + <dimen name="timepicker_text_inset_normal">26dp</dimen> + <dimen name="timepicker_text_inset_inner">58dp</dimen> + <dimen name="timepicker_text_size_normal">14sp</dimen> + <dimen name="timepicker_text_size_inner">12sp</dimen> + + <!-- Text size for the time picker header HH:MM label. This value is large + enough that we don't need to use scaled pixels, dp is fine. --> + <dimen name="timepicker_time_label_size">60dp</dimen> <dimen name="timepicker_ampm_label_size">16sp</dimen> <dimen name="timepicker_ampm_horizontal_padding">12dp</dimen> <dimen name="timepicker_ampm_vertical_padding">16dp</dimen> <dimen name="timepicker_pm_top_padding">3dp</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 --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 8814138..af8ff41 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2614,6 +2614,7 @@ <public type="attr" name="start" /> <public type="attr" name="end" /> <public type="attr" name="windowHasLightStatusBar" /> + <public type="attr" name="numbersInnerTextColor" /> <public type="style" name="Widget.Material.Button.Colored" /> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index c618707..d75e496 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -653,7 +653,8 @@ please see styles_device_defaults.xml. <item name="headerAmPmTextAppearance">@style/TextAppearance.Material.TimePicker.AmPmLabel</item> <item name="headerSelectedTextColor">?attr/textColorPrimaryInverse</item> <item name="headerBackground">@drawable/time_picker_header_material</item> - <item name="numbersTextColor">?attr/textColorSecondaryActivated</item> + <item name="numbersTextColor">?attr/textColorPrimaryActivated</item> + <item name="numbersInnerTextColor">?attr/textColorSecondaryActivated</item> <item name="numbersBackgroundColor">#10ffffff</item> <item name="numbersSelectorColor">?attr/colorControlActivated</item> <item name="amPmTextColor">?attr/textColorSecondary</item> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index b414634..241bd51 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1996,15 +1996,13 @@ <java-symbol type="string" name="deleted_key" /> <java-symbol type="string" name="sans_serif" /> <java-symbol type="string" name="radial_numbers_typeface" /> - <java-symbol type="dimen" name="timepicker_text_size_multiplier_inner" /> - <java-symbol type="dimen" name="timepicker_text_size_multiplier_outer" /> - <java-symbol type="dimen" name="timepicker_text_size_multiplier_normal" /> - <java-symbol type="dimen" name="timepicker_numbers_radius_multiplier_outer" /> - <java-symbol type="dimen" name="timepicker_selection_radius_multiplier" /> - <java-symbol type="dimen" name="timepicker_numbers_radius_multiplier_inner" /> - <java-symbol type="dimen" name="timepicker_numbers_radius_multiplier_normal" /> - <java-symbol type="dimen" name="timepicker_transition_mid_radius_multiplier" /> - <java-symbol type="dimen" name="timepicker_transition_end_radius_multiplier" /> + <java-symbol type="dimen" name="timepicker_selector_radius" /> + <java-symbol type="dimen" name="timepicker_selector_dot_radius" /> + <java-symbol type="dimen" name="timepicker_center_dot_radius" /> + <java-symbol type="dimen" name="timepicker_text_inset_normal" /> + <java-symbol type="dimen" name="timepicker_text_inset_inner" /> + <java-symbol type="dimen" name="timepicker_text_size_normal" /> + <java-symbol type="dimen" name="timepicker_text_size_inner" /> <java-symbol type="string" name="battery_saver_description" /> <java-symbol type="string" name="downtime_condition_summary" /> <java-symbol type="string" name="downtime_condition_line_one" /> |