Add support for setTint in all Drawables, clean up lint warnings

Change-Id: I962089ca59684cef28cb4a648d4a91e542bdf5d4
This commit is contained in:
Alan Viverette
2014-06-14 12:57:55 -07:00
parent c25c727937
commit b3c56086d8
20 changed files with 362 additions and 156 deletions

View File

@@ -32,7 +32,7 @@ public interface Animatable {
/**
* Indicates whether the animation is running.
*
*
* @return True if the animation is running, false otherwise.
*/
boolean isRunning();

View File

@@ -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;

View File

@@ -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.
* <p>
@@ -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;

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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.
* <p>
* 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);
}
}

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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(

View File

@@ -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) {}
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);
}
/**

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -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<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
private PorterDuffColorFilter mTintFilter;
public VectorDrawable() {
mVectorState = new VectorDrawableState(null);
}
@@ -147,6 +152,9 @@ public class VectorDrawable extends Drawable {
if (theme != null && canApplyTheme()) {
applyTheme(theme);
}
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
}
Object getTargetByName(String name) {
@@ -182,10 +190,45 @@ public class VectorDrawable extends Drawable {
@Override
public void setColorFilter(ColorFilter colorFilter) {
mVectorState.mVPathRenderer.setColorFilter(colorFilter);
final VectorDrawableState state = mVectorState;
if (colorFilter != null) {
// Color filter overrides tint.
mTintFilter = null;
} else if (state.mTint != null && state.mTintMode != null) {
// Restore the tint filter, if we need one.
final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT);
mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
colorFilter = mTintFilter;
}
state.mVPathRenderer.setColorFilter(colorFilter);
invalidateSelf();
}
@Override
public void setTint(ColorStateList tint, Mode tintMode) {
final VectorDrawableState state = mVectorState;
if (state.mTint != tint || state.mTintMode != tintMode) {
state.mTint = tint;
state.mTintMode = tintMode;
mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
invalidateSelf();
}
}
@Override
protected boolean onStateChange(int[] stateSet) {
final VectorDrawableState state = mVectorState;
if (state.mTint != null && state.mTintMode != null) {
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
return true;
}
return false;
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
@@ -397,6 +440,8 @@ public class VectorDrawable extends Drawable {
int mChangingConfigurations;
VPathRenderer mVPathRenderer;
Rect mPadding;
ColorStateList mTint;
Mode mTintMode;
public VectorDrawableState(VectorDrawableState copy) {
if (copy != null) {
@@ -404,6 +449,8 @@ public class VectorDrawable extends Drawable {
// TODO: Make sure the constant state are handled correctly.
mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
mPadding = new Rect(copy.mPadding);
mTint = copy.mTint;
mTintMode = copy.mTintMode;
}
}