From f2525f6802219ad5e983128dc2f7b5a89a507d9c Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Tue, 24 Mar 2015 18:03:38 -0700 Subject: Clean up time picker attributes and drawing code Change-Id: I16283d666f49885855a5f9bb3781cea07af058fd --- api/current.txt | 8 +- api/system-current.txt | 8 +- core/java/android/widget/RadialTimePickerView.java | 141 +++++++-------------- .../android/widget/TimePickerClockDelegate.java | 126 +++++++++++++----- ...mary_text_secondary_when_activated_material.xml | 8 ++ ...t_secondary_when_activated_material_inverse.xml | 8 ++ .../res/color/time_picker_header_text_material.xml | 8 -- core/res/res/layout-land/time_picker_material.xml | 5 + .../res/res/layout/time_picker_header_material.xml | 7 + core/res/res/values/attrs.xml | 36 ++++-- core/res/res/values/styles_material.xml | 8 +- 11 files changed, 208 insertions(+), 155 deletions(-) create mode 100644 core/res/res/color/primary_text_secondary_when_activated_material.xml create mode 100644 core/res/res/color/primary_text_secondary_when_activated_material_inverse.xml delete mode 100644 core/res/res/color/time_picker_header_text_material.xml diff --git a/api/current.txt b/api/current.txt index d8d8998..c325761 100644 --- a/api/current.txt +++ b/api/current.txt @@ -303,8 +303,8 @@ package android { field public static final int alphabeticShortcut = 16843235; // 0x10101e3 field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef field public static final int alwaysRetainTaskState = 16843267; // 0x1010203 - field public static final int amPmBackgroundColor = 16843941; // 0x10104a5 - field public static final int amPmTextColor = 16843940; // 0x10104a4 + field public static final deprecated int amPmBackgroundColor = 16843941; // 0x10104a5 + field public static final deprecated int amPmTextColor = 16843940; // 0x10104a4 field public static final int ambientShadowAlpha = 16843966; // 0x10104be field public static final int angle = 16843168; // 0x10101a0 field public static final int animateFirstView = 16843477; // 0x10102d5 @@ -650,12 +650,12 @@ package android { field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e field public static final int hardwareAccelerated = 16843475; // 0x10102d3 field public static final int hasCode = 16842764; // 0x101000c - field public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0 + field public static final deprecated int headerAmPmTextAppearance = 16843936; // 0x10104a0 field public static final int headerBackground = 16843055; // 0x101012f field public static final deprecated int headerDayOfMonthTextAppearance = 16843927; // 0x1010497 field public static final int headerDividersEnabled = 16843310; // 0x101022e field public static final deprecated int headerMonthTextAppearance = 16843926; // 0x1010496 - field public static final int headerTimeTextAppearance = 16843935; // 0x101049f + field public static final deprecated int headerTimeTextAppearance = 16843935; // 0x101049f field public static final int headerYearTextAppearance = 16843928; // 0x1010498 field public static final int height = 16843093; // 0x1010155 field public static final int hideOnContentScroll = 16843843; // 0x1010443 diff --git a/api/system-current.txt b/api/system-current.txt index 71474a3..9766bd9 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -375,8 +375,8 @@ package android { field public static final int alphabeticShortcut = 16843235; // 0x10101e3 field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef field public static final int alwaysRetainTaskState = 16843267; // 0x1010203 - field public static final int amPmBackgroundColor = 16843941; // 0x10104a5 - field public static final int amPmTextColor = 16843940; // 0x10104a4 + field public static final deprecated int amPmBackgroundColor = 16843941; // 0x10104a5 + field public static final deprecated int amPmTextColor = 16843940; // 0x10104a4 field public static final int ambientShadowAlpha = 16843966; // 0x10104be field public static final int angle = 16843168; // 0x10101a0 field public static final int animateFirstView = 16843477; // 0x10102d5 @@ -722,12 +722,12 @@ package android { field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e field public static final int hardwareAccelerated = 16843475; // 0x10102d3 field public static final int hasCode = 16842764; // 0x101000c - field public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0 + field public static final deprecated int headerAmPmTextAppearance = 16843936; // 0x10104a0 field public static final int headerBackground = 16843055; // 0x101012f field public static final deprecated int headerDayOfMonthTextAppearance = 16843927; // 0x1010497 field public static final int headerDividersEnabled = 16843310; // 0x101022e field public static final deprecated int headerMonthTextAppearance = 16843926; // 0x1010496 - field public static final int headerTimeTextAppearance = 16843935; // 0x101049f + field public static final deprecated int headerTimeTextAppearance = 16843935; // 0x101049f field public static final int headerYearTextAppearance = 16843928; // 0x1010498 field public static final int height = 16843093; // 0x1010155 field public static final int hideOnContentScroll = 16843843; // 0x1010443 diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java index 20aa972..143dea4 100644 --- a/core/java/android/widget/RadialTimePickerView.java +++ b/core/java/android/widget/RadialTimePickerView.java @@ -122,8 +122,9 @@ public class RadialTimePickerView extends View { private final Paint mPaintCenter = new Paint(); private final Paint[][] mPaintSelector = new Paint[2][3]; - private final int[][] mColorSelector = new int[2][3]; - private final IntHolder[][] mAlphaSelector = new IntHolder[2][3]; + + private final int mSelectorColor; + private final int mSelectorDotColor; private final Paint mPaintBackground = new Paint(); @@ -147,6 +148,8 @@ public class RadialTimePickerView extends View { private final RadialPickerTouchHelper mTouchHelper; + private final Path mSelectorPath = new Path(); + private boolean mIs24HourMode; private boolean mShowHours; @@ -316,11 +319,6 @@ public class RadialTimePickerView extends View { for (int i = 0; i < mAlpha.length; i++) { mAlpha[i] = new IntHolder(ALPHA_OPAQUE); } - for (int i = 0; i < mAlphaSelector.length; i++) { - for (int j = 0; j < mAlphaSelector[i].length; j++) { - mAlphaSelector[i][j] = new IntHolder(ALPHA_OPAQUE); - } - } mTextColor[HOURS] = a.getColorStateList(R.styleable.TimePicker_numbersTextColor); mTextColor[HOURS_INNER] = a.getColorStateList(R.styleable.TimePicker_numbersInnerTextColor); @@ -345,33 +343,28 @@ public class RadialTimePickerView extends View { final int[] activatedStateSet = StateSet.get( StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_ACTIVATED); + mSelectorColor = selectorActivatedColor; + mSelectorDotColor = mTextColor[HOURS].getColorForState(activatedStateSet, 0); + mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true); - mColorSelector[HOURS][SELECTOR_CIRCLE] = selectorActivatedColor; mPaintSelector[HOURS][SELECTOR_DOT] = new Paint(); mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true); - mColorSelector[HOURS][SELECTOR_DOT] = - mTextColor[HOURS].getColorForState(activatedStateSet, 0); mPaintSelector[HOURS][SELECTOR_LINE] = new Paint(); mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2); - mColorSelector[HOURS][SELECTOR_LINE] = selectorActivatedColor; mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true); - mColorSelector[MINUTES][SELECTOR_CIRCLE] = selectorActivatedColor; mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint(); mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true); - mColorSelector[MINUTES][SELECTOR_DOT] = - mTextColor[MINUTES].getColorForState(activatedStateSet, 0); mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2); - mColorSelector[MINUTES][SELECTOR_LINE] = selectorActivatedColor; mPaintBackground.setColor(a.getColor(R.styleable.TimePicker_numbersBackgroundColor, context.getColor(R.color.timepicker_default_numbers_background_color_material))); @@ -600,8 +593,8 @@ public class RadialTimePickerView extends View { // Initialize the hours and minutes numbers. for (int i = 0; i < 12; i++) { mHours12Texts[i] = String.format("%d", HOURS_NUMBERS[i]); - mOuterHours24Texts[i] = String.format("%02d", HOURS_NUMBERS_24[i]); - mInnerHours24Texts[i] = String.format("%d", HOURS_NUMBERS[i]); + mInnerHours24Texts[i] = String.format("%02d", HOURS_NUMBERS_24[i]); + mOuterHours24Texts[i] = String.format("%d", HOURS_NUMBERS[i]); mMinutesTexts[i] = String.format("%02d", MINUTES_NUMBERS[i]); } } @@ -612,22 +605,16 @@ public class RadialTimePickerView extends View { mInnerTextHours = mInnerHours24Texts; } else { mOuterTextHours = mHours12Texts; - mInnerTextHours = null; + mInnerTextHours = mHours12Texts; } mOuterTextMinutes = mMinutesTexts; final int hoursAlpha = mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT; mAlpha[HOURS].setValue(hoursAlpha); - mAlphaSelector[HOURS][SELECTOR_CIRCLE].setValue(hoursAlpha); - mAlphaSelector[HOURS][SELECTOR_DOT].setValue(hoursAlpha); - mAlphaSelector[HOURS][SELECTOR_LINE].setValue(hoursAlpha); final int minutesAlpha = mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE; mAlpha[MINUTES].setValue(minutesAlpha); - mAlphaSelector[MINUTES][SELECTOR_CIRCLE].setValue(minutesAlpha); - mAlphaSelector[MINUTES][SELECTOR_DOT].setValue(minutesAlpha); - mAlphaSelector[MINUTES][SELECTOR_LINE].setValue(minutesAlpha); } @Override @@ -675,7 +662,7 @@ public class RadialTimePickerView extends View { mOuterTextHours, mOuterTextX[HOURS], mOuterTextY[HOURS], mPaint[HOURS], hoursAlpha, !mIsOnInnerCircle, mSelectionDegrees[HOURS], false); - // Draw inner hours (12-23) for 24-hour time. + // Draw inner hours (13-00) for 24-hour time. if (mIs24HourMode && mInnerTextHours != null) { drawTextElements(canvas, mTextSize[HOURS_INNER], mTypeface, mTextColor[HOURS_INNER], mInnerTextHours, mInnerTextX, mInnerTextY, mPaint[HOURS], hoursAlpha, @@ -714,69 +701,61 @@ public class RadialTimePickerView extends View { canvas.drawCircle(mXCenter, mYCenter, mCenterDotRadius, mPaintCenter); } + private int applyAlpha(int argb, int alpha) { + final int srcAlpha = (argb >> 24) & 0xFF; + final int dstAlpha = (int) (srcAlpha * (alpha / 255.0) + 0.5f); + return (0xFFFFFF & argb) | (dstAlpha << 24); + } + private int getMultipliedAlpha(int argb, int alpha) { return (int) (Color.alpha(argb) * (alpha / 255.0) + 0.5); } - private final Path mSelectorPath = new Path(); - private void drawSelector(Canvas canvas, int index, Path selectorPath, float alphaMod) { - // Calculate the current radius at which to place the selection circle. - mLineLength[index] = mCircleRadius - mTextInset[index]; - - final double selectionRadians = Math.toRadians(mSelectionDegrees[index]); - - float pointX = mXCenter + (int) (mLineLength[index] * Math.sin(selectionRadians)); - float pointY = mYCenter - (int) (mLineLength[index] * Math.cos(selectionRadians)); + final int alpha = (int) (mAlpha[index % 2].getValue() * alphaMod + 0.5f); + final int color = applyAlpha(mSelectorColor, alpha); - int color; - int alpha; - Paint paint; - - // Draw the selection circle - color = mColorSelector[index % 2][SELECTOR_CIRCLE]; - alpha = (int) (mAlphaSelector[index % 2][SELECTOR_CIRCLE].getValue() * alphaMod + 0.5f); - paint = mPaintSelector[index % 2][SELECTOR_CIRCLE]; + // Calculate the current radius at which to place the selection circle. + final int selRadius = mSelectorRadius; + final int selLength = mCircleRadius - mTextInset[index]; + final double selAngleRad = Math.toRadians(mSelectionDegrees[index]); + final float selCenterX = mXCenter + selLength * (float) Math.sin(selAngleRad); + final float selCenterY = mYCenter - selLength * (float) Math.cos(selAngleRad); + + // Draw the selection circle. + final Paint paint = mPaintSelector[index % 2][SELECTOR_CIRCLE]; paint.setColor(color); - paint.setAlpha(getMultipliedAlpha(color, alpha)); - canvas.drawCircle(pointX, pointY, mSelectorRadius, paint); + canvas.drawCircle(selCenterX, selCenterY, selRadius, paint); // If needed, set up the clip path for later. if (selectorPath != null) { - mSelectorPath.reset(); - mSelectorPath.addCircle(pointX, pointY, mSelectorRadius, Path.Direction.CCW); + selectorPath.reset(); + selectorPath.addCircle(selCenterX, selCenterY, selRadius, Path.Direction.CCW); } - // Draw the dot if needed. + // Draw the dot if we're between two items. final boolean shouldDrawDot = mSelectionDegrees[index] % 30 != 0; if (shouldDrawDot) { - // We're not on a direct tick - color = mColorSelector[index % 2][SELECTOR_DOT]; - 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, mSelectorDotRadius, paint); + final Paint dotPaint = mPaintSelector[index % 2][SELECTOR_DOT]; + dotPaint.setColor(color); + canvas.drawCircle(selCenterX, selCenterY, mSelectorDotRadius, dotPaint); } // 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 double sin = Math.sin(selAngleRad); + final double cos = Math.cos(selAngleRad); + final int lineLength = selLength - selRadius; 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 = (int) (mAlphaSelector[index % 2][SELECTOR_LINE].getValue() * alphaMod + 0.5f); - paint = mPaintSelector[index % 2][SELECTOR_LINE]; - paint.setColor(color); - paint.setStrokeWidth(mSelectorStroke); - paint.setAlpha(getMultipliedAlpha(color, alpha)); - canvas.drawLine(mXCenter, mYCenter, pointX, pointY, paint); + final float linePointX = centerX + (int) (lineLength * sin); + final float linePointY = centerY - (int) (lineLength * cos); + + // Draw the line. + final Paint linePaint = mPaintSelector[index % 2][SELECTOR_LINE]; + linePaint.setColor(color); + linePaint.setStrokeWidth(mSelectorStroke); + canvas.drawLine(mXCenter, mYCenter, linePointX, linePointY, linePaint); } private void calculatePositionsHours() { @@ -890,21 +869,8 @@ public class RadialTimePickerView extends View { if (mHoursToMinutesAnims.size() == 0) { mHoursToMinutesAnims.add(getFadeOutAnimator(mAlpha[HOURS], ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_CIRCLE], - ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_DOT], - ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_LINE], - ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeInAnimator(mAlpha[MINUTES], ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_CIRCLE], - ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_DOT], - ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); - mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_LINE], - ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); } if (mTransition != null && mTransition.isRunning()) { @@ -919,21 +885,8 @@ public class RadialTimePickerView extends View { if (mMinuteToHoursAnims.size() == 0) { mMinuteToHoursAnims.add(getFadeOutAnimator(mAlpha[MINUTES], ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_CIRCLE], - ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_DOT], - ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_LINE], - ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeInAnimator(mAlpha[HOURS], ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_CIRCLE], - ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_DOT], - ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); - mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_LINE], - ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener)); } if (mTransition != null && mTransition.isRunning()) { diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java index 9fdd718..718d216 100644 --- a/core/java/android/widget/TimePickerClockDelegate.java +++ b/core/java/android/widget/TimePickerClockDelegate.java @@ -16,16 +16,20 @@ package android.widget; +import android.annotation.Nullable; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.Log; +import android.util.StateSet; import android.util.TypedValue; import android.view.HapticFeedbackConstants; import android.view.KeyCharacterMap; @@ -48,7 +52,6 @@ import java.util.Locale; */ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate implements RadialTimePickerView.OnValueSelectedListener { - private static final String TAG = "TimePickerClockDelegate"; // Index used by RadialPickerLayout @@ -61,14 +64,16 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl // Also NOT a real index, just used for keyboard mode. private static final int ENABLE_PICKER_INDEX = 3; + private static final int[] ATTRS_TEXT_COLOR = new int[] { + com.android.internal.R.attr.textColor}; + private static final int[] ATTRS_DISABLED_ALPHA = new int[] { + com.android.internal.R.attr.disabledAlpha}; + // LayoutLib relies on these constants. Change TimePickerClockDelegate_Delegate if // modifying these. 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 final View mHeaderView; @@ -83,8 +88,7 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl private final String mAmText; private final String mPmText; - private final float mDisabledAlpha; - + private boolean mIsEnabled = true; private boolean mAllowAutoAdvance; private int mInitialHourOfDay; private int mInitialMinute; @@ -134,7 +138,6 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl final View mainView = inflater.inflate(layoutResourceId, delegator); mHeaderView = mainView.findViewById(R.id.time_header); - mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground)); // Set up hour/minute labels. mHourView = (TextView) mainView.findViewById(R.id.hours); @@ -147,14 +150,6 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl mMinuteView.setAccessibilityDelegate( new ClickActionDelegate(context, R.string.select_minutes)); - final int headerTimeTextAppearance = a.getResourceId( - R.styleable.TimePicker_headerTimeTextAppearance, 0); - if (headerTimeTextAppearance != 0) { - mHourView.setTextAppearance(context, headerTimeTextAppearance); - mSeparatorView.setTextAppearance(context, headerTimeTextAppearance); - mMinuteView.setTextAppearance(context, headerTimeTextAppearance); - } - // Now that we have text appearances out of the way, make sure the hour // and minute views are correctly sized. mHourView.setMinWidth(computeStableWidth(mHourView, 24)); @@ -169,19 +164,40 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl mPmLabel.setText(amPmStrings[1]); mPmLabel.setOnClickListener(mClickListener); - final int headerAmPmTextAppearance = a.getResourceId( - R.styleable.TimePicker_headerAmPmTextAppearance, 0); - if (headerAmPmTextAppearance != 0) { - mAmLabel.setTextAppearance(context, headerAmPmTextAppearance); - mPmLabel.setTextAppearance(context, headerAmPmTextAppearance); + // For the sake of backwards compatibility, attempt to extract the text + // color from the header time text appearance. If it's set, we'll let + // that override the "real" header text color. + ColorStateList headerTextColor = null; + + @SuppressWarnings("deprecation") + final int timeHeaderTextAppearance = a.getResourceId( + R.styleable.TimePicker_headerTimeTextAppearance, 0); + if (timeHeaderTextAppearance != 0) { + final TypedArray textAppearance = mContext.obtainStyledAttributes(null, + ATTRS_TEXT_COLOR, 0, timeHeaderTextAppearance); + final ColorStateList legacyHeaderTextColor = textAppearance.getColorStateList(0); + headerTextColor = applyLegacyColorFixes(legacyHeaderTextColor); + textAppearance.recycle(); } - a.recycle(); + if (headerTextColor == null) { + headerTextColor = a.getColorStateList(R.styleable.TimePicker_headerTextColor); + } + + if (headerTextColor != null) { + mHourView.setTextColor(headerTextColor); + mSeparatorView.setTextColor(headerTextColor); + mMinuteView.setTextColor(headerTextColor); + mAmLabel.setTextColor(headerTextColor); + mPmLabel.setTextColor(headerTextColor); + } + + // Set up header background, if available. + if (a.hasValueOrEmpty(R.styleable.TimePicker_headerBackground)) { + mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground)); + } - // Pull disabled alpha from theme. - final TypedValue outValue = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); - mDisabledAlpha = outValue.getFloat(); + a.recycle(); mRadialTimePickerView = (RadialTimePickerView) mainView.findViewById( R.id.radial_picker); @@ -204,6 +220,54 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX); } + /** + * The legacy text color might have been poorly defined. Ensures that it + * has an appropriate activated state, using the selected state if one + * exists or modifying the default text color otherwise. + * + * @param color a legacy text color, or {@code null} + * @return a color state list with an appropriate activated state, or + * {@code null} if a valid activated state could not be generated + */ + @Nullable + private ColorStateList applyLegacyColorFixes(@Nullable ColorStateList color) { + if (color == null || color.hasState(R.attr.state_activated)) { + return color; + } + + final int activatedColor; + final int defaultColor; + if (color.hasState(R.attr.state_selected)) { + activatedColor = color.getColorForState(StateSet.get( + StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_SELECTED), 0); + defaultColor = color.getColorForState(StateSet.get( + StateSet.VIEW_STATE_ENABLED), 0); + } else { + activatedColor = color.getDefaultColor(); + + // Generate a non-activated color using the disabled alpha. + final TypedArray ta = mContext.obtainStyledAttributes(ATTRS_DISABLED_ALPHA); + final float disabledAlpha = ta.getFloat(0, 0.30f); + defaultColor = multiplyAlphaComponent(activatedColor, disabledAlpha); + } + + if (activatedColor == 0 || defaultColor == 0) { + // We somehow failed to obtain the colors. + return null; + } + + final int[][] stateSet = new int[][] {{ R.attr.state_activated }, {}}; + final int[] colors = new int[] { activatedColor, defaultColor }; + return new ColorStateList(stateSet, colors); + } + + private int multiplyAlphaComponent(int color, float alphaMod) { + final int srcRgb = color & 0xFFFFFF; + final int srcAlpha = (color >> 24) & 0xFF; + final int dstAlpha = (int) (srcAlpha * alphaMod + 0.5f); + return srcRgb | (dstAlpha << 24); + } + private static class ClickActionDelegate extends AccessibilityDelegate { private final AccessibilityAction mClickAction; @@ -604,12 +668,12 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl private void updateAmPmLabelStates(int amOrPm) { final boolean isAm = amOrPm == AM; + mAmLabel.setActivated(isAm); mAmLabel.setChecked(isAm); - mAmLabel.setSelected(isAm); final boolean isPm = amOrPm == PM; + mPmLabel.setActivated(isPm); mPmLabel.setChecked(isPm); - mPmLabel.setSelected(isPm); } /** @@ -769,8 +833,8 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl } } - mHourView.setSelected(index == HOUR_INDEX); - mMinuteView.setSelected(index == MINUTE_INDEX); + mHourView.setActivated(index == HOUR_INDEX); + mMinuteView.setActivated(index == MINUTE_INDEX); } private void setAmOrPm(int amOrPm) { @@ -960,9 +1024,9 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl String minuteStr = (values[1] == -1) ? mDoublePlaceholderText : String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText); mHourView.setText(hourStr); - mHourView.setSelected(false); + mHourView.setActivated(false); mMinuteView.setText(minuteStr); - mMinuteView.setSelected(false); + mMinuteView.setActivated(false); if (!mIs24HourView) { updateAmPmLabelStates(values[2]); } diff --git a/core/res/res/color/primary_text_secondary_when_activated_material.xml b/core/res/res/color/primary_text_secondary_when_activated_material.xml new file mode 100644 index 0000000..7ab4a2e --- /dev/null +++ b/core/res/res/color/primary_text_secondary_when_activated_material.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/color/primary_text_secondary_when_activated_material_inverse.xml b/core/res/res/color/primary_text_secondary_when_activated_material_inverse.xml new file mode 100644 index 0000000..baa8958 --- /dev/null +++ b/core/res/res/color/primary_text_secondary_when_activated_material_inverse.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/color/time_picker_header_text_material.xml b/core/res/res/color/time_picker_header_text_material.xml deleted file mode 100644 index cda894b..0000000 --- a/core/res/res/color/time_picker_header_text_material.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml index 1b85e8f..89c3749 100644 --- a/core/res/res/layout-land/time_picker_material.xml +++ b/core/res/res/layout-land/time_picker_material.xml @@ -53,6 +53,7 @@ android:id="@+id/hours" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Material.TimePicker.TimeLabel" android:singleLine="true" android:ellipsize="none" android:gravity="right" @@ -64,6 +65,7 @@ android:id="@+id/separator" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Material.TimePicker.TimeLabel" android:importantForAccessibility="no" tools:text=":" tools:textSize="@dimen/timepicker_time_label_size" @@ -75,6 +77,7 @@ android:id="@+id/minutes" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Material.TimePicker.TimeLabel" android:singleLine="true" android:ellipsize="none" android:gravity="left" @@ -97,6 +100,7 @@ android:id="@+id/am_label" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Material.TimePicker.AmPmLabel" android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" android:paddingTop="@dimen/timepicker_am_top_padding" @@ -111,6 +115,7 @@ android:id="@+id/pm_label" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Material.TimePicker.AmPmLabel" android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" android:paddingTop="@dimen/timepicker_pm_top_padding" diff --git a/core/res/res/layout/time_picker_header_material.xml b/core/res/res/layout/time_picker_header_material.xml index 0ef404d..be9e443 100644 --- a/core/res/res/layout/time_picker_header_material.xml +++ b/core/res/res/layout/time_picker_header_material.xml @@ -15,6 +15,8 @@ ~ limitations under the License --> + - - - - + + + - + + - + - - - - + @@ -4813,6 +4816,19 @@ + + + + + + + + + diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index f1f7462..472908c 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -381,12 +381,12 @@ please see styles_device_defaults.xml. -- cgit v1.1