diff --git a/core/api/current.txt b/core/api/current.txt index 5b639ff0b00f6..a5eb2ff1acea4 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -528,6 +528,8 @@ package android { field public static final int detailSocialSummary = 16843428; // 0x10102a4 field public static final int detailsElementBackground = 16843598; // 0x101034e field public static final int dial = 16843010; // 0x1010102 + field public static final int dialTint = 16844342; // 0x1010636 + field public static final int dialTintMode = 16844343; // 0x1010637 field public static final int dialogCornerRadius = 16844145; // 0x1010571 field public static final int dialogIcon = 16843252; // 0x10101f4 field public static final int dialogLayout = 16843255; // 0x10101f7 @@ -725,8 +727,14 @@ package android { field public static final int groupIndicator = 16843019; // 0x101010b field public static final int gwpAsanMode = 16844310; // 0x1010616 field public static final int hand_hour = 16843011; // 0x1010103 + field public static final int hand_hourTint = 16844344; // 0x1010638 + field public static final int hand_hourTintMode = 16844345; // 0x1010639 field public static final int hand_minute = 16843012; // 0x1010104 + field public static final int hand_minuteTint = 16844346; // 0x101063a + field public static final int hand_minuteTintMode = 16844347; // 0x101063b field public static final int hand_second = 16844323; // 0x1010623 + field public static final int hand_secondTint = 16844348; // 0x101063c + field public static final int hand_secondTintMode = 16844349; // 0x101063d field public static final int handle = 16843354; // 0x101025a field public static final int handleProfiling = 16842786; // 0x1010022 field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e @@ -53714,11 +53722,27 @@ package android.widget { ctor @Deprecated public AnalogClock(android.content.Context, android.util.AttributeSet); ctor @Deprecated public AnalogClock(android.content.Context, android.util.AttributeSet, int); ctor @Deprecated public AnalogClock(android.content.Context, android.util.AttributeSet, int, int); + method @Deprecated @Nullable public android.graphics.BlendMode getDialTintBlendMode(); + method @Deprecated @Nullable public android.content.res.ColorStateList getDialTintList(); + method @Deprecated @Nullable public android.graphics.BlendMode getHourHandTintBlendMode(); + method @Deprecated @Nullable public android.content.res.ColorStateList getHourHandTintList(); + method @Deprecated @Nullable public android.graphics.BlendMode getMinuteHandTintBlendMode(); + method @Deprecated @Nullable public android.content.res.ColorStateList getMinuteHandTintList(); + method @Deprecated @Nullable public android.graphics.BlendMode getSecondHandTintBlendMode(); + method @Deprecated @Nullable public android.content.res.ColorStateList getSecondHandTintList(); method @Deprecated @Nullable public String getTimeZone(); method @Deprecated public void setDial(@NonNull android.graphics.drawable.Icon); + method @Deprecated public void setDialTintBlendMode(@Nullable android.graphics.BlendMode); + method @Deprecated public void setDialTintList(@Nullable android.content.res.ColorStateList); method @Deprecated public void setHourHand(@NonNull android.graphics.drawable.Icon); + method @Deprecated public void setHourHandTintBlendMode(@Nullable android.graphics.BlendMode); + method @Deprecated public void setHourHandTintList(@Nullable android.content.res.ColorStateList); method @Deprecated public void setMinuteHand(@NonNull android.graphics.drawable.Icon); + method @Deprecated public void setMinuteHandTintBlendMode(@Nullable android.graphics.BlendMode); + method @Deprecated public void setMinuteHandTintList(@Nullable android.content.res.ColorStateList); method @Deprecated public void setSecondHand(@Nullable android.graphics.drawable.Icon); + method @Deprecated public void setSecondHandTintBlendMode(@Nullable android.graphics.BlendMode); + method @Deprecated public void setSecondHandTintList(@Nullable android.content.res.ColorStateList); method @Deprecated public void setTimeZone(@Nullable String); } diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java index 93b2d8ae3c9a0..34fe51e82e8f3 100644 --- a/core/java/android/widget/AnalogClock.java +++ b/core/java/android/widget/AnalogClock.java @@ -23,8 +23,10 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; +import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; @@ -68,12 +70,16 @@ public class AnalogClock extends View { @UnsupportedAppUsage private Drawable mHourHand; + private final TintInfo mHourHandTintInfo = new TintInfo(); @UnsupportedAppUsage private Drawable mMinuteHand; + private final TintInfo mMinuteHandTintInfo = new TintInfo(); @Nullable private Drawable mSecondHand; + private final TintInfo mSecondHandTintInfo = new TintInfo(); @UnsupportedAppUsage private Drawable mDial; + private final TintInfo mDialTintInfo = new TintInfo(); private int mDialWidth; private int mDialHeight; @@ -111,18 +117,86 @@ public class AnalogClock extends View { mDial = context.getDrawable(com.android.internal.R.drawable.clock_dial); } + ColorStateList dialTintList = a.getColorStateList( + com.android.internal.R.styleable.AnalogClock_dialTint); + if (dialTintList != null) { + mDialTintInfo.mTintList = dialTintList; + mDialTintInfo.mHasTintList = true; + } + BlendMode dialTintMode = Drawable.parseBlendMode( + a.getInt(com.android.internal.R.styleable.AnalogClock_dialTintMode, -1), + null); + if (dialTintMode != null) { + mDialTintInfo.mTintBlendMode = dialTintMode; + mDialTintInfo.mHasTintBlendMode = true; + } + if (mDialTintInfo.mHasTintList || mDialTintInfo.mHasTintBlendMode) { + mDial = mDialTintInfo.apply(mDial); + } + mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour); if (mHourHand == null) { mHourHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_hour); } + ColorStateList hourHandTintList = a.getColorStateList( + com.android.internal.R.styleable.AnalogClock_hand_hourTint); + if (hourHandTintList != null) { + mHourHandTintInfo.mTintList = hourHandTintList; + mHourHandTintInfo.mHasTintList = true; + } + BlendMode hourHandTintMode = Drawable.parseBlendMode( + a.getInt(com.android.internal.R.styleable.AnalogClock_hand_hourTintMode, -1), + null); + if (hourHandTintMode != null) { + mHourHandTintInfo.mTintBlendMode = hourHandTintMode; + mHourHandTintInfo.mHasTintBlendMode = true; + } + if (mHourHandTintInfo.mHasTintList || mHourHandTintInfo.mHasTintBlendMode) { + mHourHand = mHourHandTintInfo.apply(mHourHand); + } + mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute); if (mMinuteHand == null) { mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute); } + ColorStateList minuteHandTintList = a.getColorStateList( + com.android.internal.R.styleable.AnalogClock_hand_minuteTint); + if (minuteHandTintList != null) { + mMinuteHandTintInfo.mTintList = minuteHandTintList; + mMinuteHandTintInfo.mHasTintList = true; + } + BlendMode minuteHandTintMode = Drawable.parseBlendMode( + a.getInt(com.android.internal.R.styleable.AnalogClock_hand_minuteTintMode, -1), + null); + if (minuteHandTintMode != null) { + mMinuteHandTintInfo.mTintBlendMode = minuteHandTintMode; + mMinuteHandTintInfo.mHasTintBlendMode = true; + } + if (mMinuteHandTintInfo.mHasTintList || mMinuteHandTintInfo.mHasTintBlendMode) { + mMinuteHand = mMinuteHandTintInfo.apply(mMinuteHand); + } + mSecondHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_second); + ColorStateList secondHandTintList = a.getColorStateList( + com.android.internal.R.styleable.AnalogClock_hand_secondTint); + if (secondHandTintList != null) { + mSecondHandTintInfo.mTintList = secondHandTintList; + mSecondHandTintInfo.mHasTintList = true; + } + BlendMode secondHandTintMode = Drawable.parseBlendMode( + a.getInt(com.android.internal.R.styleable.AnalogClock_hand_secondTintMode, -1), + null); + if (secondHandTintMode != null) { + mSecondHandTintInfo.mTintBlendMode = secondHandTintMode; + mSecondHandTintInfo.mHasTintBlendMode = true; + } + if (mSecondHandTintInfo.mHasTintList || mSecondHandTintInfo.mHasTintBlendMode) { + mSecondHand = mSecondHandTintInfo.apply(mSecondHand); + } + mTimeZone = toZoneId(a.getString(com.android.internal.R.styleable.AnalogClock_timeZone)); createClock(); @@ -141,6 +215,68 @@ public class AnalogClock extends View { invalidate(); } + /** + * Applies a tint to the dial drawable. + *

+ * Subsequent calls to {@link #setDial(Icon)} will + * automatically mutate the drawable and apply the specified tint and tint + * mode using {@link Drawable#setTintList(ColorStateList)}. + * + * @param tint the tint to apply, may be {@code null} to clear tint + * + * @attr ref android.R.styleable#AnalogClock_dialTint + * @see #getDialTintList() + * @see Drawable#setTintList(ColorStateList) + */ + @RemotableViewMethod + public void setDialTintList(@Nullable ColorStateList tint) { + mDialTintInfo.mTintList = tint; + mDialTintInfo.mHasTintList = true; + + mDial = mDialTintInfo.apply(mDial); + } + + /** + * @return the tint applied to the dial drawable + * @attr ref android.R.styleable#AnalogClock_dialTint + * @see #setDialTintList(ColorStateList) + */ + @InspectableProperty(attributeId = com.android.internal.R.styleable.AnalogClock_dialTint) + @Nullable + public ColorStateList getDialTintList() { + return mDialTintInfo.mTintList; + } + + /** + * Specifies the blending mode used to apply the tint specified by + * {@link #setDialTintList(ColorStateList)}} to the dial drawable. + * The default mode is {@link BlendMode#SRC_IN}. + * + * @param blendMode the blending mode used to apply the tint, may be + * {@code null} to clear tint + * @attr ref android.R.styleable#AnalogClock_dialTintMode + * @see #getDialTintBlendMode() + * @see Drawable#setTintBlendMode(BlendMode) + */ + @RemotableViewMethod + public void setDialTintBlendMode(@Nullable BlendMode blendMode) { + mDialTintInfo.mTintBlendMode = blendMode; + mDialTintInfo.mHasTintBlendMode = true; + + mDial = mDialTintInfo.apply(mDial); + } + + /** + * @return the blending mode used to apply the tint to the dial drawable + * @attr ref android.R.styleable#AnalogClock_dialTintMode + * @see #setDialTintBlendMode(BlendMode) + */ + @InspectableProperty(attributeId = com.android.internal.R.styleable.AnalogClock_dialTintMode) + @Nullable + public BlendMode getDialTintBlendMode() { + return mDialTintInfo.mTintBlendMode; + } + /** Sets the hour hand of the clock to the specified Icon. */ @RemotableViewMethod public void setHourHand(@NonNull Icon icon) { @@ -150,6 +286,71 @@ public class AnalogClock extends View { invalidate(); } + /** + * Applies a tint to the hour hand drawable. + *

+ * Subsequent calls to {@link #setHourHand(Icon)} will + * automatically mutate the drawable and apply the specified tint and tint + * mode using {@link Drawable#setTintList(ColorStateList)}. + * + * @param tint the tint to apply, may be {@code null} to clear tint + * + * @attr ref android.R.styleable#AnalogClock_hand_hourTint + * @see #getHourHandTintList() + * @see Drawable#setTintList(ColorStateList) + */ + @RemotableViewMethod + public void setHourHandTintList(@Nullable ColorStateList tint) { + mHourHandTintInfo.mTintList = tint; + mHourHandTintInfo.mHasTintList = true; + + mHourHand = mHourHandTintInfo.apply(mHourHand); + } + + /** + * @return the tint applied to the hour hand drawable + * @attr ref android.R.styleable#AnalogClock_hand_hourTint + * @see #setHourHandTintList(ColorStateList) + */ + @InspectableProperty( + attributeId = com.android.internal.R.styleable.AnalogClock_hand_hourTint + ) + @Nullable + public ColorStateList getHourHandTintList() { + return mHourHandTintInfo.mTintList; + } + + /** + * Specifies the blending mode used to apply the tint specified by + * {@link #setHourHandTintList(ColorStateList)}} to the hour hand drawable. + * The default mode is {@link BlendMode#SRC_IN}. + * + * @param blendMode the blending mode used to apply the tint, may be + * {@code null} to clear tint + * @attr ref android.R.styleable#AnalogClock_hand_hourTintMode + * @see #getHourHandTintBlendMode() + * @see Drawable#setTintBlendMode(BlendMode) + */ + @RemotableViewMethod + public void setHourHandTintBlendMode(@Nullable BlendMode blendMode) { + mHourHandTintInfo.mTintBlendMode = blendMode; + mHourHandTintInfo.mHasTintBlendMode = true; + + mHourHand = mHourHandTintInfo.apply(mHourHand); + } + + /** + * @return the blending mode used to apply the tint to the hour hand drawable + * @attr ref android.R.styleable#AnalogClock_hand_hourTintMode + * @see #setHourHandTintBlendMode(BlendMode) + */ + @InspectableProperty( + attributeId = com.android.internal.R.styleable.AnalogClock_hand_hourTintMode) + @Nullable + public BlendMode getHourHandTintBlendMode() { + return mHourHandTintInfo.mTintBlendMode; + } + /** Sets the minute hand of the clock to the specified Icon. */ @RemotableViewMethod public void setMinuteHand(@NonNull Icon icon) { @@ -159,6 +360,71 @@ public class AnalogClock extends View { invalidate(); } + /** + * Applies a tint to the minute hand drawable. + *

+ * Subsequent calls to {@link #setMinuteHand(Icon)} will + * automatically mutate the drawable and apply the specified tint and tint + * mode using {@link Drawable#setTintList(ColorStateList)}. + * + * @param tint the tint to apply, may be {@code null} to clear tint + * + * @attr ref android.R.styleable#AnalogClock_hand_minuteTint + * @see #getMinuteHandTintList() + * @see Drawable#setTintList(ColorStateList) + */ + @RemotableViewMethod + public void setMinuteHandTintList(@Nullable ColorStateList tint) { + mMinuteHandTintInfo.mTintList = tint; + mMinuteHandTintInfo.mHasTintList = true; + + mMinuteHand = mMinuteHandTintInfo.apply(mMinuteHand); + } + + /** + * @return the tint applied to the minute hand drawable + * @attr ref android.R.styleable#AnalogClock_hand_minuteTint + * @see #setMinuteHandTintList(ColorStateList) + */ + @InspectableProperty( + attributeId = com.android.internal.R.styleable.AnalogClock_hand_minuteTint + ) + @Nullable + public ColorStateList getMinuteHandTintList() { + return mMinuteHandTintInfo.mTintList; + } + + /** + * Specifies the blending mode used to apply the tint specified by + * {@link #setMinuteHandTintList(ColorStateList)}} to the minute hand drawable. + * The default mode is {@link BlendMode#SRC_IN}. + * + * @param blendMode the blending mode used to apply the tint, may be + * {@code null} to clear tint + * @attr ref android.R.styleable#AnalogClock_hand_minuteTintMode + * @see #getMinuteHandTintBlendMode() + * @see Drawable#setTintBlendMode(BlendMode) + */ + @RemotableViewMethod + public void setMinuteHandTintBlendMode(@Nullable BlendMode blendMode) { + mMinuteHandTintInfo.mTintBlendMode = blendMode; + mMinuteHandTintInfo.mHasTintBlendMode = true; + + mMinuteHand = mMinuteHandTintInfo.apply(mMinuteHand); + } + + /** + * @return the blending mode used to apply the tint to the minute hand drawable + * @attr ref android.R.styleable#AnalogClock_hand_minuteTintMode + * @see #setMinuteHandTintBlendMode(BlendMode) + */ + @InspectableProperty( + attributeId = com.android.internal.R.styleable.AnalogClock_hand_minuteTintMode) + @Nullable + public BlendMode getMinuteHandTintBlendMode() { + return mMinuteHandTintInfo.mTintBlendMode; + } + /** * Sets the second hand of the clock to the specified Icon, or hides the second hand if it is * null. @@ -172,6 +438,71 @@ public class AnalogClock extends View { invalidate(); } + /** + * Applies a tint to the second hand drawable. + *

+ * Subsequent calls to {@link #setSecondHand(Icon)} will + * automatically mutate the drawable and apply the specified tint and tint + * mode using {@link Drawable#setTintList(ColorStateList)}. + * + * @param tint the tint to apply, may be {@code null} to clear tint + * + * @attr ref android.R.styleable#AnalogClock_hand_secondTint + * @see #getSecondHandTintList() + * @see Drawable#setTintList(ColorStateList) + */ + @RemotableViewMethod + public void setSecondHandTintList(@Nullable ColorStateList tint) { + mSecondHandTintInfo.mTintList = tint; + mSecondHandTintInfo.mHasTintList = true; + + mSecondHand = mSecondHandTintInfo.apply(mSecondHand); + } + + /** + * @return the tint applied to the second hand drawable + * @attr ref android.R.styleable#AnalogClock_hand_secondTint + * @see #setSecondHandTintList(ColorStateList) + */ + @InspectableProperty( + attributeId = com.android.internal.R.styleable.AnalogClock_hand_secondTint + ) + @Nullable + public ColorStateList getSecondHandTintList() { + return mSecondHandTintInfo.mTintList; + } + + /** + * Specifies the blending mode used to apply the tint specified by + * {@link #setSecondHandTintList(ColorStateList)}} to the second hand drawable. + * The default mode is {@link BlendMode#SRC_IN}. + * + * @param blendMode the blending mode used to apply the tint, may be + * {@code null} to clear tint + * @attr ref android.R.styleable#AnalogClock_hand_secondTintMode + * @see #getSecondHandTintBlendMode() + * @see Drawable#setTintBlendMode(BlendMode) + */ + @RemotableViewMethod + public void setSecondHandTintBlendMode(@Nullable BlendMode blendMode) { + mSecondHandTintInfo.mTintBlendMode = blendMode; + mSecondHandTintInfo.mHasTintBlendMode = true; + + mSecondHand = mSecondHandTintInfo.apply(mSecondHand); + } + + /** + * @return the blending mode used to apply the tint to the second hand drawable + * @attr ref android.R.styleable#AnalogClock_hand_secondTintMode + * @see #setSecondHandTintBlendMode(BlendMode) + */ + @InspectableProperty( + attributeId = com.android.internal.R.styleable.AnalogClock_hand_secondTintMode) + @Nullable + public BlendMode getSecondHandTintBlendMode() { + return mSecondHandTintInfo.mTintBlendMode; + } + /** * Indicates which time zone is currently used by this view. * @@ -462,4 +793,36 @@ public class AnalogClock extends View { return null; } } + + private final class TintInfo { + boolean mHasTintList; + @Nullable ColorStateList mTintList; + boolean mHasTintBlendMode; + @Nullable BlendMode mTintBlendMode; + + /** + * Returns a mutated copy of {@code drawable} with tinting applied, or null if it's null. + */ + @Nullable + Drawable apply(@Nullable Drawable drawable) { + if (drawable == null) return null; + + Drawable newDrawable = drawable.mutate(); + + if (mHasTintList) { + newDrawable.setTintList(mTintList); + } + + if (mHasTintBlendMode) { + newDrawable.setTintBlendMode(mTintBlendMode); + } + + // All drawables should have the same state as the View itself. + if (drawable.isStateful()) { + newDrawable.setState(getDrawableState()); + } + + return newDrawable; + } + } } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 99f58ee1f8a63..735e122444ef5 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4127,6 +4127,94 @@ user's time zone. Please refer to {@link java.util.TimeZone} for more information about time zone ids. --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index a1ea61c447c02..4732e5fbf84fa 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3076,6 +3076,14 @@ + + + + + + + +