OSDN Git Service

Clean up time picker attributes and drawing code
authorAlan Viverette <alanv@google.com>
Wed, 25 Mar 2015 01:03:38 +0000 (18:03 -0700)
committerAlan Viverette <alanv@google.com>
Wed, 25 Mar 2015 01:03:38 +0000 (18:03 -0700)
Change-Id: I16283d666f49885855a5f9bb3781cea07af058fd

api/current.txt
api/system-current.txt
core/java/android/widget/RadialTimePickerView.java
core/java/android/widget/TimePickerClockDelegate.java
core/res/res/color/primary_text_secondary_when_activated_material.xml [new file with mode: 0644]
core/res/res/color/primary_text_secondary_when_activated_material_inverse.xml [moved from core/res/res/color/time_picker_header_text_material.xml with 83% similarity]
core/res/res/layout-land/time_picker_material.xml
core/res/res/layout/time_picker_header_material.xml
core/res/res/values/attrs.xml
core/res/res/values/styles_material.xml

index d8d8998..c325761 100644 (file)
@@ -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
index 71474a3..9766bd9 100644 (file)
@@ -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
index 20aa972..143dea4 100644 (file)
@@ -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()) {
index 9fdd718..718d216 100644 (file)
 
 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 (file)
index 0000000..7ab4a2e
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_activated="true"
+        android:color="?attr/textColorPrimary" />
+    <item
+        android:color="?attr/textColorSecondary" />
+</selector>
\ No newline at end of file
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_selected="true"
+        android:state_activated="true"
         android:color="?attr/textColorPrimaryInverse" />
     <item
         android:color="?attr/textColorSecondaryInverse" />
index 1b85e8f..89c3749 100644 (file)
@@ -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"
                 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"
                 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"
index 0ef404d..be9e443 100644 (file)
@@ -15,6 +15,8 @@
   ~ limitations under the License
   -->
 
+<!-- This layout is duplicated in land/time_picker_material.xml, so any
+     changes made here need to be manually copied over. -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 xmlns:tools="http://schemas.android.com/tools"
                 android:id="@+id/time_header"
@@ -32,6 +34,7 @@
         android:layout_height="wrap_content"
         android:layout_toLeftOf="@+id/separator"
         android:layout_alignBaseline="@+id/separator"
+        android:textAppearance="@style/TextAppearance.Material.TimePicker.TimeLabel"
         android:singleLine="true"
         android:ellipsize="none"
         android:gravity="right"
@@ -46,6 +49,7 @@
         android:layout_marginLeft="@dimen/timepicker_separator_padding"
         android:layout_marginRight="@dimen/timepicker_separator_padding"
         android:layout_centerInParent="true"
+        android:textAppearance="@style/TextAppearance.Material.TimePicker.TimeLabel"
         android:importantForAccessibility="no"
         tools:text=":"
         tools:textSize="@dimen/timepicker_time_label_size"
@@ -59,6 +63,7 @@
         android:layout_height="wrap_content"
         android:layout_toRightOf="@+id/separator"
         android:layout_alignBaseline="@+id/separator"
+        android:textAppearance="@style/TextAppearance.Material.TimePicker.TimeLabel"
         android:singleLine="true"
         android:ellipsize="none"
         android:gravity="left"
@@ -83,6 +88,7 @@
             android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
             android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
             android:paddingTop="@dimen/timepicker_am_top_padding"
+            android:textAppearance="@style/TextAppearance.Material.TimePicker.AmPmLabel"
             android:lines="1"
             android:ellipsize="none"
             tools:text="AM"
             android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
             android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
             android:paddingTop="@dimen/timepicker_pm_top_padding"
+            android:textAppearance="@style/TextAppearance.Material.TimePicker.AmPmLabel"
             android:lines="1"
             android:ellipsize="none"
             tools:text="PM"
index b5576c5..8897775 100644 (file)
         <attr name="legacyLayout" format="reference" />
         <!-- @hide The layout of the time picker. -->
         <attr name="internalLayout" />
-        <!-- The text appearance for the AM/PM header. -->
-        <attr name="headerAmPmTextAppearance" format="reference" />
-        <!-- The text appearance for the time header. -->
-        <attr name="headerTimeTextAppearance" format="reference" />
+
+        <!-- The text color for the selected time header text, ex. "12" or
+             "PM". This should be a color state list where the activated state
+             will be used when the minute picker or hour picker is active.-->
+        <attr name="headerTextColor" />
         <!-- The background for the header containing the currently selected time. -->
         <attr name="headerBackground" />
-        <!-- The color for the hours/minutes numbers. -->
+
+        <!-- The color for the hours/minutes numbers. This should be a color
+             state list where the activated state will be used when the number
+             is active.-->
         <attr name="numbersTextColor" format="color" />
-        <!-- The color for the inner hours numbers used in 24-hour mode. -->
+        <!-- The color for the inner hours numbers used in 24-hour mode. This
+             should be a color state list where the activated state will be
+             used when the number is active.-->
         <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. -->
-        <attr name="amPmTextColor" format="color" />
-        <!-- The background color state list for the AM/PM selectors. -->
-        <attr name="amPmBackgroundColor" format="color" />
         <!-- The color for the hours/minutes selector. -->
         <attr name="numbersSelectorColor" format="color" />
+
         <!-- Defines the look of the widget. Prior to the L release, the only choice was
              spinner. As of L, with the Material theme selected, the default layout is clock,
              but this attribute can be used to force spinner to be used instead. -->
             <!-- Time picker with clock face to select the time. -->
             <enum name="clock" value="2" />
         </attr>
+
+        <!-- The text appearance for the AM/PM header.
+             @deprecated Use headerTextColor instead. -->
+        <attr name="headerAmPmTextAppearance" format="reference" />
+        <!-- The text appearance for the time header.
+             @deprecated Use headerTextColor instead. -->
+        <attr name="headerTimeTextAppearance" format="reference" />
+        <!-- The color for the AM/PM selectors.
+             {@deprecated Use headerTextColor instead.}-->
+        <attr name="amPmTextColor" format="color" />
+        <!-- The background color state list for the AM/PM selectors.
+             {@deprecated Use headerBackground instead.}-->
+        <attr name="amPmBackgroundColor" format="color" />
     </declare-styleable>
 
     <!-- ========================= -->
index f1f7462..472908c 100644 (file)
@@ -381,12 +381,12 @@ please see styles_device_defaults.xml.
 
     <style name="TextAppearance.Material.TimePicker.TimeLabel" parent="TextAppearance.Material">
         <item name="textSize">@dimen/timepicker_time_label_size</item>
-        <item name="textColor">@color/time_picker_header_text_material</item>
+        <item name="textColor">@color/primary_text_secondary_when_activated_material_inverse</item>
     </style>
 
     <style name="TextAppearance.Material.TimePicker.AmPmLabel" parent="TextAppearance.Material.Button">
         <item name="textSize">@dimen/timepicker_ampm_label_size</item>
-        <item name="textColor">@color/time_picker_header_text_material</item>
+        <item name="textColor">@color/primary_text_secondary_when_activated_material_inverse</item>
     </style>
 
     <style name="TextAppearance.Material.DatePicker.DayOfWeekLabel" parent="TextAppearance.Material">
@@ -660,8 +660,7 @@ please see styles_device_defaults.xml.
         <item name="legacyLayout">@layout/time_picker_legacy_material</item>
         <!-- Attributes for new-style TimePicker. -->
         <item name="internalLayout">@layout/time_picker_material</item>
-        <item name="headerTimeTextAppearance">@style/TextAppearance.Material.TimePicker.TimeLabel</item>
-        <item name="headerAmPmTextAppearance">@style/TextAppearance.Material.TimePicker.AmPmLabel</item>
+        <item name="headerTextColor">@color/primary_text_secondary_when_activated_material</item>
         <item name="headerBackground">#ff555555</item>
         <item name="numbersTextColor">?attr/textColorPrimaryActivated</item>
         <item name="numbersInnerTextColor">?attr/textColorSecondaryActivated</item>
@@ -1033,6 +1032,7 @@ please see styles_device_defaults.xml.
     <style name="Widget.Material.Light.NumberPicker" parent="Widget.Material.NumberPicker"/>
 
     <style name="Widget.Material.Light.TimePicker" parent="Widget.Material.TimePicker">
+        <item name="headerTextColor">@color/primary_text_secondary_when_activated_material_inverse</item>
         <item name="headerBackground">?attr/colorAccent</item>
         <item name="numbersBackgroundColor">#ffeeeeee</item>
     </style>