diff --git a/graphics/java/android/graphics/drawable/Animatable.java b/graphics/java/android/graphics/drawable/Animatable.java index 9dc62c36d6180..4edfad4fd7dd3 100644 --- a/graphics/java/android/graphics/drawable/Animatable.java +++ b/graphics/java/android/graphics/drawable/Animatable.java @@ -32,7 +32,7 @@ public interface Animatable { /** * Indicates whether the animation is running. - * + * * @return True if the animation is running, false otherwise. */ boolean isRunning(); diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java index e8024f7864f0e..0fd442382dd64 100644 --- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java @@ -19,6 +19,8 @@ package android.graphics.drawable; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.ColorFilter; +import android.graphics.PorterDuff.Mode; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.Resources.Theme; @@ -88,6 +90,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac canvas.restoreToCount(saveCount); } + @Override public void start() { if (!mRunning) { mRunning = true; @@ -95,11 +98,13 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac } } + @Override public void stop() { mRunning = false; unscheduleSelf(this); } + @Override public boolean isRunning() { return mRunning; } @@ -108,10 +113,11 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac unscheduleSelf(this); scheduleSelf(this, SystemClock.uptimeMillis() + mState.mFrameDuration); } - + + @Override public void run() { // TODO: This should be computed in draw(Canvas), based on the amount - // of time since the last frame drawn + // of time since the last frame drawn mCurrentDegrees += mIncrement; if (mCurrentDegrees > (360.0f - mIncrement)) { mCurrentDegrees = 0.0f; @@ -119,7 +125,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac invalidateSelf(); nextFrame(); } - + @Override public boolean setVisible(boolean visible, boolean restart) { mState.mDrawable.setVisible(visible, restart); @@ -133,8 +139,8 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac unscheduleSelf(this); } return changed; - } - + } + /** * Returns the drawable rotated by this RotateDrawable. */ @@ -148,7 +154,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac | mState.mChangingConfigurations | mState.mDrawable.getChangingConfigurations(); } - + @Override public void setAlpha(int alpha) { mState.mDrawable.setAlpha(alpha); @@ -164,11 +170,17 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac mState.mDrawable.setColorFilter(cf); } + @Override + public void setTint(ColorStateList tint, Mode tintMode) { + mState.mDrawable.setTint(tint, tintMode); + } + @Override public int getOpacity() { return mState.mDrawable.getOpacity(); } + @Override public void invalidateDrawable(Drawable who) { final Callback callback = getCallback(); if (callback != null) { @@ -176,6 +188,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac } } + @Override public void scheduleDrawable(Drawable who, Runnable what, long when) { final Callback callback = getCallback(); if (callback != null) { @@ -183,6 +196,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac } } + @Override public void unscheduleDrawable(Drawable who, Runnable what) { final Callback callback = getCallback(); if (callback != null) { @@ -194,7 +208,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac public boolean getPadding(Rect padding) { return mState.mDrawable.getPadding(padding); } - + @Override public boolean isStateful() { return mState.mDrawable.isStateful(); @@ -205,6 +219,16 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac mState.mDrawable.setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom); } + @Override + protected boolean onLevelChange(int level) { + return mState.mDrawable.setLevel(level); + } + + @Override + protected boolean onStateChange(int[] state) { + return mState.mDrawable.setState(state); + } + @Override public int getIntrinsicWidth() { return mState.mDrawable.getIntrinsicWidth(); @@ -231,11 +255,11 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac final TypedArray a = r.obtainAttributes(attrs, R.styleable.AnimatedRotateDrawable); super.inflateWithAttributes(r, parser, a, R.styleable.AnimatedRotateDrawable_visible); - + TypedValue tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotX); final boolean pivotXRel = tv.type == TypedValue.TYPE_FRACTION; final float pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); - + tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotY); final boolean pivotYRel = tv.type == TypedValue.TYPE_FRACTION; final float pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); @@ -250,7 +274,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac } a.recycle(); - + int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && @@ -306,7 +330,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac Drawable mDrawable; int mChangingConfigurations; - + boolean mPivotXRel; float mPivotX; boolean mPivotYRel; @@ -315,7 +339,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac int mFramesCount; private boolean mCanConstantState; - private boolean mCheckedConstantState; + private boolean mCheckedConstantState; public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner, Resources res) { @@ -341,12 +365,12 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac public Drawable newDrawable() { return new AnimatedRotateDrawable(this, null); } - + @Override public Drawable newDrawable(Resources res) { return new AnimatedRotateDrawable(this, res); } - + @Override public int getChangingConfigurations() { return mChangingConfigurations; diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index 1ee022490e7bf..074076151d564 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -28,7 +28,6 @@ import android.os.SystemClock; import android.util.AttributeSet; /** - * * An object used to create frame-by-frame animations, defined by a series of Drawable objects, * which can be used as a View object's background. *
@@ -114,6 +113,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An * @see #isRunning() * @see #stop() */ + @Override public void start() { if (!isRunning()) { run(); @@ -127,6 +127,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An * @see #isRunning() * @see #start() */ + @Override public void stop() { if (isRunning()) { unscheduleSelf(this); @@ -138,6 +139,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An * * @return true if the animation is running, false otherwise */ + @Override public boolean isRunning() { return mAnimating; } @@ -148,6 +150,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An * * @see #start() */ + @Override public void run() { nextFrame(false); } @@ -165,41 +168,41 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An public int getNumberOfFrames() { return mAnimationState.getChildCount(); } - + /** * @return The Drawable at the specified frame index */ public Drawable getFrame(int index) { return mAnimationState.getChild(index); } - + /** - * @return The duration in milliseconds of the frame at the + * @return The duration in milliseconds of the frame at the * specified index */ public int getDuration(int i) { return mAnimationState.mDurations[i]; } - + /** * @return True of the animation will play once, false otherwise */ public boolean isOneShot() { return mAnimationState.mOneShot; } - + /** * Sets whether the animation should play once or repeat. - * + * * @param oneShot Pass true if the animation should only play once */ public void setOneShot(boolean oneShot) { mAnimationState.mOneShot = oneShot; } - + /** * Add a frame to the animation - * + * * @param frame The frame to add * @param duration How long in milliseconds the frame should appear */ @@ -209,7 +212,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An setFrame(0, true, false); } } - + private void nextFrame(boolean unschedule) { int next = mCurFrame+1; final int N = mAnimationState.getChildCount(); @@ -239,21 +242,21 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An @Override public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException { - + TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.AnimationDrawable); super.inflateWithAttributes(r, parser, a, com.android.internal.R.styleable.AnimationDrawable_visible); - + mAnimationState.setVariablePadding(a.getBoolean( com.android.internal.R.styleable.AnimationDrawable_variablePadding, false)); - + mAnimationState.mOneShot = a.getBoolean( com.android.internal.R.styleable.AnimationDrawable_oneshot, false); - + a.recycle(); - + int type; final int innerDepth = parser.getDepth()+1; @@ -267,7 +270,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An if (depth > innerDepth || !parser.getName().equals("item")) { continue; } - + a = r.obtainAttributes(attrs, com.android.internal.R.styleable.AnimationDrawableItem); int duration = a.getInt( com.android.internal.R.styleable.AnimationDrawableItem_duration, -1); @@ -278,9 +281,9 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } int drawableRes = a.getResourceId( com.android.internal.R.styleable.AnimationDrawableItem_drawable, 0); - + a.recycle(); - + Drawable dr; if (drawableRes != 0) { dr = r.getDrawable(drawableRes); @@ -295,7 +298,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } dr = Drawable.createFromXmlInner(r, parser, attrs, theme); } - + mAnimationState.addFrame(dr, duration); if (dr != null) { dr.setCallback(this); @@ -342,7 +345,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } public void addFrame(Drawable dr, int dur) { - // Do not combine the following. The array index must be evaluated before + // Do not combine the following. The array index must be evaluated before // the array is accessed because super.addChild(dr) has a side effect on mDurations. int pos = super.addChild(dr); mDurations[pos] = dur; diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index ef6c0859f6663..be940df215e78 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -31,6 +31,7 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; +import android.graphics.drawable.ColorDrawable.ColorState; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Shader; @@ -618,9 +619,11 @@ public class BitmapDrawable extends Drawable { @Override public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) { - mBitmapState.mTint = tint; - mBitmapState.mTintMode = tintMode; - computeTintFilter(); + final BitmapState state = mBitmapState; + state.mTint = tint; + state.mTintMode = tintMode; + + mTintFilter = updateTintFilter(mTintFilter, tint, tintMode); invalidateSelf(); } @@ -638,21 +641,6 @@ public class BitmapDrawable extends Drawable { return mBitmapState.mTintMode; } - private void computeTintFilter() { - final BitmapState state = mBitmapState; - if (state.mTint != null && state.mTintMode != null) { - final int color = state.mTint.getColorForState(getState(), 0); - if (mTintFilter != null) { - mTintFilter.setColor(color); - mTintFilter.setMode(state.mTintMode); - } else { - mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); - } - } else { - mTintFilter = null; - } - } - /** * @hide Candidate for future API inclusion */ @@ -679,17 +667,11 @@ public class BitmapDrawable extends Drawable { @Override protected boolean onStateChange(int[] stateSet) { - final ColorStateList tint = mBitmapState.mTint; - if (tint != null) { - final int newColor = tint.getColorForState(stateSet, 0); - final int oldColor = mTintFilter.getColor(); - if (oldColor != newColor) { - mTintFilter.setColor(newColor); - invalidateSelf(); - return true; - } + final BitmapState state = mBitmapState; + if (state.mTint != null && state.mTintMode != null) { + mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); + return true; } - return false; } @@ -946,7 +928,7 @@ public class BitmapDrawable extends Drawable { mTargetDensity = state.mTargetDensity; } - computeTintFilter(); + updateTintFilter(mTintFilter, state.mTint, state.mTintMode); computeBitmapSize(); } } diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java index 3ac99727b53ee..174de3ae7c548 100644 --- a/graphics/java/android/graphics/drawable/ClipDrawable.java +++ b/graphics/java/android/graphics/drawable/ClipDrawable.java @@ -19,10 +19,12 @@ package android.graphics.drawable; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.Resources.Theme; import android.graphics.*; +import android.graphics.PorterDuff.Mode; import android.view.Gravity; import android.util.AttributeSet; @@ -52,7 +54,7 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { public static final int HORIZONTAL = 1; public static final int VERTICAL = 2; - + ClipDrawable() { this(null, null); } @@ -111,6 +113,7 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { // overrides from Drawable.Callback + @Override public void invalidateDrawable(Drawable who) { final Callback callback = getCallback(); if (callback != null) { @@ -118,6 +121,7 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { } } + @Override public void scheduleDrawable(Drawable who, Runnable what, long when) { final Callback callback = getCallback(); if (callback != null) { @@ -125,6 +129,7 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { } } + @Override public void unscheduleDrawable(Drawable who, Runnable what) { final Callback callback = getCallback(); if (callback != null) { @@ -168,6 +173,11 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { mClipState.mDrawable.setColorFilter(cf); } + @Override + public void setTint(ColorStateList tint, Mode tintMode) { + mClipState.mDrawable.setTint(tint, tintMode); + } + @Override public int getOpacity() { return mClipState.mDrawable.getOpacity(); @@ -197,7 +207,7 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { @Override public void draw(Canvas canvas) { - + if (mClipState.mDrawable.getLevel() == 0) { return; } diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index df5ca33b91114..37161826e0edb 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -17,6 +17,8 @@ package android.graphics.drawable; import android.graphics.*; +import android.graphics.PorterDuff.Mode; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; @@ -39,9 +41,13 @@ import java.io.IOException; * @attr ref android.R.styleable#ColorDrawable_color */ public class ColorDrawable extends Drawable { + private final Paint mPaint = new Paint(); + @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_") private ColorState mColorState; - private final Paint mPaint = new Paint(); + private ColorStateList mTint; + private PorterDuffColorFilter mTintFilter; + private boolean mMutated; /** @@ -84,9 +90,17 @@ public class ColorDrawable extends Drawable { @Override public void draw(Canvas canvas) { - if ((mColorState.mUseColor >>> 24) != 0) { + final ColorFilter colorFilter = mPaint.getColorFilter(); + if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null || mTintFilter != null) { + if (colorFilter == null) { + mPaint.setColorFilter(mTintFilter); + } + mPaint.setColor(mColorState.mUseColor); canvas.drawRect(getBounds(), mPaint); + + // Restore original color filter. + mPaint.setColorFilter(colorFilter); } } @@ -141,16 +155,51 @@ public class ColorDrawable extends Drawable { } /** - * Setting a color filter on a ColorDrawable has no effect. + * Sets the color filter applied to this color. + *
+ * Only supported on version {@link android.os.Build.VERSION_CODES#L} and
+ * above. Calling this method has no effect on earlier versions.
*
- * @param colorFilter Ignore.
+ * @see android.graphics.drawable.Drawable#setColorFilter(ColorFilter)
*/
@Override
public void setColorFilter(ColorFilter colorFilter) {
+ mPaint.setColorFilter(colorFilter);
+ }
+
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ final ColorState state = mColorState;
+ if (state.mTint != tint || state.mTintMode != tintMode) {
+ state.mTint = tint;
+ state.mTintMode = tintMode;
+
+ mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
+ invalidateSelf();
+ }
+ }
+
+ @Override
+ protected boolean onStateChange(int[] stateSet) {
+ final ColorState state = mColorState;
+ if (state.mTint != null && state.mTintMode != null) {
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mTint != null && mTint.isStateful();
}
@Override
public int getOpacity() {
+ if (mTintFilter != null || mPaint.getColorFilter() != null) {
+ return PixelFormat.TRANSLUCENT;
+ }
+
switch (mColorState.mUseColor >>> 24) {
case 255:
return PixelFormat.OPAQUE;
@@ -165,8 +214,7 @@ public class ColorDrawable extends Drawable {
throws XmlPullParserException, IOException {
super.inflate(r, parser, attrs, theme);
- final TypedArray a = obtainAttributes(
- r, theme, attrs, R.styleable.ColorDrawable);
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ColorDrawable);
inflateStateFromTypedArray(a);
a.recycle();
}
@@ -225,21 +273,25 @@ public class ColorDrawable extends Drawable {
}
final static class ColorState extends ConstantState {
+ int[] mThemeAttrs;
int mBaseColor; // base color, independent of setAlpha()
@ViewDebug.ExportedProperty
int mUseColor; // basecolor modulated by setAlpha()
int mChangingConfigurations;
- int[] mThemeAttrs;
+ ColorStateList mTint;
+ Mode mTintMode;
ColorState() {
// Empty constructor.
}
ColorState(ColorState state) {
+ mThemeAttrs = state.mThemeAttrs;
mBaseColor = state.mBaseColor;
mUseColor = state.mUseColor;
mChangingConfigurations = state.mChangingConfigurations;
- mThemeAttrs = state.mThemeAttrs;
+ mTint = state.mTint;
+ mTintMode = state.mTintMode;
}
@Override
@@ -276,6 +328,6 @@ public class ColorDrawable extends Drawable {
mColorState = state;
}
- // No local properties to initialize.
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 6a7757b912e79..cb88e3da28ad5 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -17,13 +17,6 @@
package android.graphics.drawable;
import android.annotation.NonNull;
-import android.graphics.Insets;
-import android.graphics.Xfermode;
-import android.os.Trace;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -31,15 +24,19 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
+import android.graphics.Insets;
import android.graphics.NinePatch;
import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
-import android.graphics.PorterDuff.Mode;
+import android.graphics.Xfermode;
+import android.os.Trace;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.StateSet;
@@ -47,6 +44,9 @@ import android.util.TypedValue;
import android.util.Xml;
import android.view.View;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
@@ -1225,6 +1225,26 @@ public abstract class Drawable {
return new BitmapDrawable(res, bm);
}
+ /**
+ * Ensures the tint filter is consistent with the current tint color and
+ * mode.
+ */
+ PorterDuffColorFilter updateTintFilter(PorterDuffColorFilter tintFilter, ColorStateList tint,
+ PorterDuff.Mode tintMode) {
+ if (tint == null || tintMode == null) {
+ return null;
+ }
+
+ final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
+ if (tintFilter == null) {
+ return new PorterDuffColorFilter(color, tintMode);
+ }
+
+ tintFilter.setColor(color);
+ tintFilter.setMode(tintMode);
+ return tintFilter;
+ }
+
/**
* Obtains styled attributes from the theme, if available, or unstyled
* resources if the theme is null.
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 2aef39fc3e525..8be6eb745c09f 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -16,6 +16,7 @@
package android.graphics.drawable;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.graphics.Canvas;
@@ -23,6 +24,7 @@ import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.PorterDuff.Mode;
import android.os.SystemClock;
import android.util.LayoutDirection;
import android.util.SparseArray;
@@ -151,7 +153,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public void setColorFilter(ColorFilter cf) {
- mDrawableContainerState.mHasColorFilter = true;
+ mDrawableContainerState.mHasColorFilter = (cf != null);
if (mDrawableContainerState.mColorFilter != cf) {
mDrawableContainerState.mColorFilter = cf;
@@ -162,6 +164,20 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
}
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ mDrawableContainerState.mHasTint = (tint != null && tintMode != null);
+
+ if (mDrawableContainerState.mTint != tint || mDrawableContainerState.mTintMode != tintMode) {
+ mDrawableContainerState.mTint = tint;
+ mDrawableContainerState.mTintMode = tintMode;
+
+ if (mCurrDrawable != null) {
+ mCurrDrawable.mutate().setTint(tint, tintMode);
+ }
+ }
+ }
+
/**
* Change the global fade duration when a new drawable is entering
* the scene.
@@ -396,6 +412,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
if (mDrawableContainerState.mHasColorFilter) {
d.setColorFilter(mDrawableContainerState.mColorFilter);
+ } else if (mDrawableContainerState.mHasTint) {
+ d.setTint(mDrawableContainerState.mTint, mDrawableContainerState.mTintMode);
}
d.setVisible(isVisible(), true);
d.setDither(mDrawableContainerState.mDither);
@@ -566,6 +584,10 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
ColorFilter mColorFilter;
boolean mHasColorFilter;
+ ColorStateList mTint;
+ Mode mTintMode;
+ boolean mHasTint;
+
DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
mOwner = owner;
@@ -588,6 +610,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mAutoMirrored = orig.mAutoMirrored;
mColorFilter = orig.mColorFilter;
mHasColorFilter = orig.mHasColorFilter;
+ mTint = orig.mTint;
+ mTintMode = orig.mTintMode;
+ mHasTint = orig.mHasTint;
// Cloning the following values may require creating futures.
mConstantPadding = orig.getConstantPadding();
@@ -741,7 +766,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
final int N = mNumChildren;
final Drawable[] drawables = mDrawables;
for (int i = 0; i < N; i++) {
- final Drawable d = drawables[i];
+ final Drawable d = drawables[i];
if (d != null) {
if (d.canApplyTheme()) {
return true;
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 9e0ab86e18c5c..220e81c5c7d1b 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -19,10 +19,12 @@ package android.graphics.drawable;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
import android.graphics.*;
+import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.util.Log;
@@ -44,8 +46,7 @@ import java.io.IOException;
* @attr ref android.R.styleable#InsetDrawable_insetTop
* @attr ref android.R.styleable#InsetDrawable_insetBottom
*/
-public class InsetDrawable extends Drawable implements Drawable.Callback
-{
+public class InsetDrawable extends Drawable implements Drawable.Callback {
// Most of this is copied from ScaleDrawable.
private InsetState mInsetState;
private final Rect mTmpRect = new Rect();
@@ -62,13 +63,13 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
public InsetDrawable(Drawable drawable, int insetLeft, int insetTop,
int insetRight, int insetBottom) {
this(null, null);
-
+
mInsetState.mDrawable = drawable;
mInsetState.mInsetLeft = insetLeft;
mInsetState.mInsetTop = insetTop;
mInsetState.mInsetRight = insetRight;
mInsetState.mInsetBottom = insetBottom;
-
+
if (drawable != null) {
drawable.setCallback(this);
}
@@ -78,7 +79,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
int type;
-
+
TypedArray a = r.obtainAttributes(attrs,
com.android.internal.R.styleable.InsetDrawable);
@@ -168,7 +169,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
| mInsetState.mChangingConfigurations
| mInsetState.mDrawable.getChangingConfigurations();
}
-
+
@Override
public boolean getPadding(Rect padding) {
boolean pad = mInsetState.mDrawable.getPadding(padding);
@@ -178,7 +179,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
padding.top += mInsetState.mInsetTop;
padding.bottom += mInsetState.mInsetBottom;
- if (pad || (mInsetState.mInsetLeft | mInsetState.mInsetRight |
+ if (pad || (mInsetState.mInsetLeft | mInsetState.mInsetRight |
mInsetState.mInsetTop | mInsetState.mInsetBottom) != 0) {
return true;
} else {
@@ -217,6 +218,11 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
mInsetState.mDrawable.setColorFilter(cf);
}
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ mInsetState.mDrawable.setTint(tint, tintMode);
+ }
+
/** {@hide} */
@Override
public void setLayoutDirection(int layoutDirection) {
@@ -227,7 +233,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
public int getOpacity() {
return mInsetState.mDrawable.getOpacity();
}
-
+
@Override
public boolean isStateful() {
return mInsetState.mDrawable.isStateful();
@@ -239,7 +245,12 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
onBoundsChange(getBounds());
return changed;
}
-
+
+ @Override
+ protected boolean onLevelChange(int level) {
+ return mInsetState.mDrawable.setLevel(level);
+ }
+
@Override
protected void onBoundsChange(Rect bounds) {
final Rect r = mTmpRect;
@@ -321,12 +332,12 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
public Drawable newDrawable() {
return new InsetDrawable(this, null);
}
-
+
@Override
public Drawable newDrawable(Resources res) {
return new InsetDrawable(this, res);
}
-
+
@Override
public int getChangingConfigurations() {
return mChangingConfigurations;
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 27f0a9d7c80c2..5cea7c9263041 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -16,12 +16,14 @@
package android.graphics.drawable;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
@@ -630,6 +632,15 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
}
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ final ChildDrawable[] array = mLayerState.mChildren;
+ final int N = mLayerState.mNum;
+ for (int i = 0; i < N; i++) {
+ array[i].mDrawable.setTint(tint, tintMode);
+ }
+ }
+
/**
* Sets the opacity of this drawable directly, instead of collecting the
* states from the layers
diff --git a/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java b/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java
index 9e56f67f4b23f..c484094f0ff57 100644
--- a/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java
+++ b/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java
@@ -27,8 +27,10 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
+import android.graphics.PorterDuff.Mode;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -67,6 +69,7 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
private final Ring mRing;
private MaterialProgressState mState;
+ private PorterDuffColorFilter mTintFilter;
/** Canvas rotation in degrees. */
private float mRotation;
@@ -106,6 +109,8 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
float insets = minEdge / 2.0f - state.mInnerRadius;
ring.setInsets(insets);
}
+
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
}
@Override
@@ -118,15 +123,21 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
}
@Override
- protected boolean onStateChange(int[] state) {
- boolean changed = super.onStateChange(state);
+ protected boolean onStateChange(int[] stateSet) {
+ boolean changed = super.onStateChange(stateSet);
- final int color = mState.mColor.getColorForState(state, Color.TRANSPARENT);
+ final MaterialProgressState state = mState;
+ final int color = state.mColor.getColorForState(stateSet, Color.TRANSPARENT);
if (color != mRing.getColor()) {
mRing.setColor(color);
changed = true;
}
+ if (state.mTint != null && state.mTintMode != null) {
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ changed = true;
+ }
+
return changed;
}
@@ -223,11 +234,24 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
return mRing.getColorFilter();
}
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ if (mState.mTint != tint || mState.mTintMode != tintMode) {
+ mState.mTint = tint;
+ mState.mTintMode = tintMode;
+
+ mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
+ invalidateSelf();
+ }
+ }
+
+ @SuppressWarnings("unused")
private void setRotation(float rotation) {
mRotation = rotation;
invalidateSelf();
}
+ @SuppressWarnings("unused")
private float getRotation() {
return mRotation;
}
@@ -331,6 +355,8 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
private int mWidth = -1;
private int mHeight = -1;
private ColorStateList mColor = ColorStateList.valueOf(Color.TRANSPARENT);
+ private ColorStateList mTint = null;
+ private Mode mTintMode = null;
public MaterialProgressState(MaterialProgressState orig) {
if (orig != null) {
@@ -340,6 +366,8 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
mWidth = orig.mWidth;
mHeight = orig.mHeight;
mColor = orig.mColor;
+ mTint = orig.mTint;
+ mTintMode = orig.mTintMode;
}
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index fea68ee1a4db8..36ffdddf5bdc1 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -327,25 +327,12 @@ public class NinePatchDrawable extends Drawable {
@Override
public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
- mNinePatchState.mTint = tint;
- mNinePatchState.mTintMode = tintMode;
- computeTintFilter();
- invalidateSelf();
- }
-
- private void computeTintFilter() {
final NinePatchState state = mNinePatchState;
- if (state.mTint != null && state.mTintMode != null) {
- final int color = state.mTint.getColorForState(getState(), 0);
- if (mTintFilter != null) {
- mTintFilter.setColor(color);
- mTintFilter.setMode(state.mTintMode);
- } else {
- mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
- }
- } else {
- mTintFilter = null;
- }
+ state.mTint = tint;
+ state.mTintMode = tintMode;
+
+ mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
+ invalidateSelf();
}
@Override
@@ -549,15 +536,10 @@ public class NinePatchDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
- final ColorStateList tint = mNinePatchState.mTint;
- if (tint != null) {
- final int newColor = tint.getColorForState(stateSet, 0);
- final int oldColor = mTintFilter.getColor();
- if (oldColor != newColor) {
- mTintFilter.setColor(newColor);
- invalidateSelf();
- return true;
- }
+ final NinePatchState state = mNinePatchState;
+ if (state.mTint != null && state.mTintMode != null) {
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ return true;
}
return false;
@@ -689,7 +671,7 @@ public class NinePatchDrawable extends Drawable {
mPadding = new Rect(state.mPadding);
}
- computeTintFilter();
+ updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
setNinePatch(state.mNinePatch);
}
}
diff --git a/graphics/java/android/graphics/drawable/PaintDrawable.java b/graphics/java/android/graphics/drawable/PaintDrawable.java
index c71cda1697372..a82e7b950edf2 100644
--- a/graphics/java/android/graphics/drawable/PaintDrawable.java
+++ b/graphics/java/android/graphics/drawable/PaintDrawable.java
@@ -35,7 +35,7 @@ public class PaintDrawable extends ShapeDrawable {
public PaintDrawable(int color) {
getPaint().setColor(color);
}
-
+
/**
* Specify radius for the corners of the rectangle. If this is > 0, then the
* drawable is drawn in a round-rectangle, rather than a rectangle.
@@ -51,7 +51,7 @@ public class PaintDrawable extends ShapeDrawable {
}
setCornerRadii(radii);
}
-
+
/**
* Specify radii for each of the 4 corners. For each corner, the array
* contains 2 values, [X_radius, Y_radius]. The corners are ordered
@@ -78,9 +78,9 @@ public class PaintDrawable extends ShapeDrawable {
int radius = a.getDimensionPixelSize(
com.android.internal.R.styleable.DrawableCorners_radius, 0);
setCornerRadius(radius);
-
+
// now check of they have any per-corner radii
-
+
int topLeftRadius = a.getDimensionPixelSize(
com.android.internal.R.styleable.DrawableCorners_topLeftRadius, radius);
int topRightRadius = a.getDimensionPixelSize(
diff --git a/graphics/java/android/graphics/drawable/PictureDrawable.java b/graphics/java/android/graphics/drawable/PictureDrawable.java
index cb2d8f67a4baa..6dcda1f565908 100644
--- a/graphics/java/android/graphics/drawable/PictureDrawable.java
+++ b/graphics/java/android/graphics/drawable/PictureDrawable.java
@@ -25,7 +25,7 @@ import android.graphics.Rect;
/**
* Drawable subclass that wraps a Picture, allowing the picture to be used
- * whereever a Drawable is supported.
+ * wherever a Drawable is supported.
*/
public class PictureDrawable extends Drawable {
@@ -40,7 +40,7 @@ public class PictureDrawable extends Drawable {
public PictureDrawable(Picture picture) {
mPicture = picture;
}
-
+
/**
* Return the picture associated with the drawable. May be null.
*
@@ -49,7 +49,7 @@ public class PictureDrawable extends Drawable {
public Picture getPicture() {
return mPicture;
}
-
+
/**
* Associate a picture with this drawable. The picture may be null.
*
@@ -58,7 +58,7 @@ public class PictureDrawable extends Drawable {
public void setPicture(Picture picture) {
mPicture = picture;
}
-
+
@Override
public void draw(Canvas canvas) {
if (mPicture != null) {
@@ -86,16 +86,16 @@ public class PictureDrawable extends Drawable {
// not sure, so be safe
return PixelFormat.TRANSLUCENT;
}
-
+
@Override
public void setFilterBitmap(boolean filter) {}
-
+
@Override
public void setDither(boolean dither) {}
-
+
@Override
public void setColorFilter(ColorFilter colorFilter) {}
-
+
@Override
public void setAlpha(int alpha) {}
}
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 06aeb983b2e31..8f8fa98c8acda 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -22,6 +22,8 @@ import org.xmlpull.v1.XmlPullParserException;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
+import android.graphics.PorterDuff.Mode;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
@@ -136,6 +138,11 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
mState.mDrawable.setColorFilter(cf);
}
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ mState.mDrawable.setTint(tint, tintMode);
+ }
+
@Override
public int getOpacity() {
return mState.mDrawable.getOpacity();
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index f090c11bd13e2..46c92fe82dfb0 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -19,10 +19,12 @@ package android.graphics.drawable;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
import android.graphics.*;
+import android.graphics.PorterDuff.Mode;
import android.view.Gravity;
import android.util.AttributeSet;
@@ -187,6 +189,11 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
mScaleState.mDrawable.setColorFilter(cf);
}
+ @Override
+ public void setTint(ColorStateList tint, Mode tintMode) {
+ mScaleState.mDrawable.setTint(tint, tintMode);
+ }
+
@Override
public int getOpacity() {
return mScaleState.mDrawable.getOpacity();
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 024f77cf2e7fc..a2aef215c2a38 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -91,10 +91,7 @@ public class ShapeDrawable extends Drawable {
private ShapeDrawable(ShapeState state) {
mShapeState = new ShapeState(state);
- if (state != null && state.mTint != null) {
- final int color = state.mTint.getColorForState(getState(), 0);
- mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
- }
+ updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
}
/**
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index b2fac9bef74c5..f359fdd0b475b 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -235,10 +235,10 @@ public class StateListDrawable extends DrawableContainer {
public Drawable getStateDrawable(int index) {
return mStateListState.getChild(index);
}
-
+
/**
* Gets the index of the drawable with the provided state set.
- *
+ *
* @param stateSet the state set to look up
* @return the index of the provided state set, or -1 if not found
* @hide pending API council
@@ -248,7 +248,7 @@ public class StateListDrawable extends DrawableContainer {
public int getStateDrawableIndex(int[] stateSet) {
return mStateListState.indexOfStateSet(stateSet);
}
-
+
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index 622e90ba4c04b..4380ca4e8145f 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -42,20 +42,20 @@ import android.os.SystemClock;
public class TransitionDrawable extends LayerDrawable implements Drawable.Callback {
/**
- * A transition is about to start.
+ * A transition is about to start.
*/
private static final int TRANSITION_STARTING = 0;
-
+
/**
* The transition has started and the animation is in progress
*/
private static final int TRANSITION_RUNNING = 1;
-
+
/**
* No transition will be applied
*/
private static final int TRANSITION_NONE = 2;
-
+
/**
* The current state of the transition. One of {@link #TRANSITION_STARTING},
* {@link #TRANSITION_RUNNING} and {@link #TRANSITION_NONE}
@@ -101,10 +101,10 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba
LayerState createConstantState(LayerState state, Resources res) {
return new TransitionState((TransitionState) state, this, res);
}
-
+
/**
* Begin the second layer on top of the first layer.
- *
+ *
* @param durationMillis The length of the transition in milliseconds
*/
public void startTransition(int durationMillis) {
@@ -116,7 +116,7 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba
mTransitionState = TRANSITION_STARTING;
invalidateSelf();
}
-
+
/**
* Show only the first layer.
*/
@@ -184,7 +184,7 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba
}
break;
}
-
+
final int alpha = mAlpha;
final boolean crossFade = mCrossFade;
final ChildDrawable[] array = mLayerState.mChildren;
@@ -217,7 +217,7 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba
d.draw(canvas);
d.setAlpha(0xFF);
}
-
+
if (!done) {
invalidateSelf();
}
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index c531c224e2e68..c3c1bcabad4e1 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -14,6 +14,7 @@
package android.graphics.drawable;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -25,8 +26,10 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.PorterDuff.Mode;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
@@ -137,6 +140,8 @@ public class VectorDrawable extends Drawable {
private final ArrayMap