diff options
Diffstat (limited to 'graphics/java/android')
22 files changed, 537 insertions, 279 deletions
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java index 9fb3fb4..c2e93a7 100644 --- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java @@ -313,6 +313,26 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac } } + @Override + public void applyTheme(Theme t) { + super.applyTheme(t); + + final AnimatedRotateState state = mState; + if (state == null) { + return; + } + + if (state.mDrawable != null) { + state.mDrawable.applyTheme(t); + } + } + + @Override + public boolean canApplyTheme() { + final AnimatedRotateState state = mState; + return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme(); + } + public void setFramesCount(int framesCount) { mState.mFramesCount = framesCount; mIncrement = 360.0f / mState.mFramesCount; @@ -331,6 +351,15 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mState.mDrawable.clearMutated(); + mMutated = false; + } + final static class AnimatedRotateState extends Drawable.ConstantState { Drawable mDrawable; diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index cb09bbf..9bcad3e 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -507,6 +507,14 @@ public class AnimatedStateListDrawable extends StateListDrawable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + static class AnimatedStateListState extends StateListState { private static final int REVERSE_SHIFT = 32; private static final int REVERSE_MASK = 0x1; diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index ad0b415..a904067 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -16,7 +16,6 @@ package android.graphics.drawable; import android.animation.Animator; import android.animation.AnimatorInflater; -import android.animation.ValueAnimator; import android.annotation.NonNull; import android.content.res.ColorStateList; import android.content.res.Resources; @@ -137,15 +136,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { private boolean mMutated; public AnimatedVectorDrawable() { - mAnimatedVectorState = new AnimatedVectorDrawableState(null); + this(null, null); } - private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res, - Theme theme) { - mAnimatedVectorState = new AnimatedVectorDrawableState(state); - if (theme != null && canApplyTheme()) { - applyTheme(theme); - } + private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res) { + mAnimatedVectorState = new AnimatedVectorDrawableState(state, mCallback, res); } @Override @@ -157,6 +152,15 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mAnimatedVectorState.mVectorDrawable.clearMutated(); + mMutated = false; + } + @Override public ConstantState getConstantState() { mAnimatedVectorState.mChangingConfigurations = getChangingConfigurations(); @@ -281,7 +285,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { VectorDrawable vectorDrawable = (VectorDrawable) res.getDrawable( drawableRes, theme).mutate(); vectorDrawable.setAllowCaching(false); + vectorDrawable.setCallback(mCallback); pathErrorScale = vectorDrawable.getPixelSize(); + if (mAnimatedVectorState.mVectorDrawable != null) { + mAnimatedVectorState.mVectorDrawable.setCallback(null); + } mAnimatedVectorState.mVectorDrawable = vectorDrawable; } a.recycle(); @@ -329,14 +337,22 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { ArrayList<Animator> mAnimators; ArrayMap<Animator, String> mTargetNameMap; - public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy) { + public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy, + Callback owner, Resources res) { if (copy != null) { mChangingConfigurations = copy.mChangingConfigurations; if (copy.mVectorDrawable != null) { - mVectorDrawable = (VectorDrawable) copy.mVectorDrawable.getConstantState().newDrawable(); - mVectorDrawable.mutate(); - mVectorDrawable.setAllowCaching(false); + final ConstantState cs = copy.mVectorDrawable.getConstantState(); + if (res != null) { + mVectorDrawable = (VectorDrawable) cs.newDrawable(res); + } else { + mVectorDrawable = (VectorDrawable) cs.newDrawable(); + } + mVectorDrawable = (VectorDrawable) mVectorDrawable.mutate(); + mVectorDrawable.setCallback(owner); + mVectorDrawable.setLayoutDirection(copy.mVectorDrawable.getLayoutDirection()); mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds()); + mVectorDrawable.setAllowCaching(false); } if (copy.mAnimators != null) { final int numAnimators = copy.mAnimators.size(); @@ -359,17 +375,12 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { @Override public Drawable newDrawable() { - return new AnimatedVectorDrawable(this, null, null); + return new AnimatedVectorDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new AnimatedVectorDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new AnimatedVectorDrawable(this, res, theme); + return new AnimatedVectorDrawable(this, res); } @Override @@ -473,4 +484,21 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { } return true; } + + private final Callback mCallback = new Callback() { + @Override + public void invalidateDrawable(Drawable who) { + invalidateSelf(); + } + + @Override + public void scheduleDrawable(Drawable who, Runnable what, long when) { + scheduleSelf(what, when); + } + + @Override + public void unscheduleDrawable(Drawable who, Runnable what) { + unscheduleSelf(what); + } + }; } diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index 9a9fd82..c730a20 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -347,6 +347,14 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + private final static class AnimationState extends DrawableContainerState { private int[] mDurations; private boolean mOneShot; diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index cf6be48..79ac651 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -132,7 +132,7 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(Bitmap bitmap) { - this(new BitmapState(bitmap), null, null); + this(new BitmapState(bitmap), null); } /** @@ -140,7 +140,7 @@ public class BitmapDrawable extends Drawable { * the display metrics of the resources. */ public BitmapDrawable(Resources res, Bitmap bitmap) { - this(new BitmapState(bitmap), res, null); + this(new BitmapState(bitmap), res); mBitmapState.mTargetDensity = mTargetDensity; } @@ -151,7 +151,7 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(String filepath) { - this(new BitmapState(BitmapFactory.decodeFile(filepath)), null, null); + this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); if (mBitmapState.mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); } @@ -162,7 +162,7 @@ public class BitmapDrawable extends Drawable { */ @SuppressWarnings("unused") public BitmapDrawable(Resources res, String filepath) { - this(new BitmapState(BitmapFactory.decodeFile(filepath)), null, null); + this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); mBitmapState.mTargetDensity = mTargetDensity; if (mBitmapState.mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); @@ -176,7 +176,7 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(java.io.InputStream is) { - this(new BitmapState(BitmapFactory.decodeStream(is)), null, null); + this(new BitmapState(BitmapFactory.decodeStream(is)), null); if (mBitmapState.mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); } @@ -187,7 +187,7 @@ public class BitmapDrawable extends Drawable { */ @SuppressWarnings("unused") public BitmapDrawable(Resources res, java.io.InputStream is) { - this(new BitmapState(BitmapFactory.decodeStream(is)), null, null); + this(new BitmapState(BitmapFactory.decodeStream(is)), null); mBitmapState.mTargetDensity = mTargetDensity; if (mBitmapState.mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); @@ -684,6 +684,14 @@ public class BitmapDrawable extends Drawable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + @Override protected boolean onStateChange(int[] stateSet) { final BitmapState state = mBitmapState; @@ -911,17 +919,12 @@ public class BitmapDrawable extends Drawable { @Override public Drawable newDrawable() { - return new BitmapDrawable(this, null, null); + return new BitmapDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new BitmapDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new BitmapDrawable(this, res, theme); + return new BitmapDrawable(this, res); } @Override @@ -934,16 +937,10 @@ public class BitmapDrawable extends Drawable { * The one constructor to rule them all. This is called by all public * constructors to set the state and initialize local properties. */ - private BitmapDrawable(BitmapState state, Resources res, Theme theme) { - if (theme != null && state.canApplyTheme()) { - // If we need to apply a theme, implicitly mutate. - mBitmapState = new BitmapState(state); - applyTheme(theme); - } else { - mBitmapState = state; - } + private BitmapDrawable(BitmapState state, Resources res) { + mBitmapState = state; - initializeWithState(state, res); + initializeWithState(mBitmapState, res); } /** diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java index 40711cf..669cef2 100644 --- a/graphics/java/android/graphics/drawable/ClipDrawable.java +++ b/graphics/java/android/graphics/drawable/ClipDrawable.java @@ -55,6 +55,8 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { public static final int HORIZONTAL = 1; public static final int VERTICAL = 2; + private boolean mMutated; + ClipDrawable() { this(null, null); } @@ -112,6 +114,26 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { dr.setCallback(this); } + @Override + public void applyTheme(Theme t) { + super.applyTheme(t); + + final ClipState state = mClipState; + if (state == null) { + return; + } + + if (state.mDrawable != null) { + state.mDrawable.applyTheme(t); + } + } + + @Override + public boolean canApplyTheme() { + final ClipState state = mClipState; + return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme(); + } + // overrides from Drawable.Callback @Override @@ -268,6 +290,24 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { super.setLayoutDirection(layoutDirection); } + @Override + public Drawable mutate() { + if (!mMutated && super.mutate() == this) { + mClipState.mDrawable.mutate(); + mMutated = true; + } + return this; + } + + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mClipState.mDrawable.clearMutated(); + mMutated = false; + } + final static class ClipState extends ConstantState { Drawable mDrawable; int mChangingConfigurations; diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 1253c46..0f0c844 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -88,6 +88,14 @@ public class ColorDrawable extends Drawable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + @Override public void draw(Canvas canvas) { final ColorFilter colorFilter = mPaint.getColorFilter(); @@ -291,17 +299,12 @@ public class ColorDrawable extends Drawable { @Override public Drawable newDrawable() { - return new ColorDrawable(this, null, null); + return new ColorDrawable(this); } @Override public Drawable newDrawable(Resources res) { - return new ColorDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new ColorDrawable(this, res, theme); + return new ColorDrawable(this); } @Override @@ -310,14 +313,8 @@ public class ColorDrawable extends Drawable { } } - private ColorDrawable(ColorState state, Resources res, Theme theme) { - if (theme != null && state.canApplyTheme()) { - mColorState = new ColorState(state); - applyTheme(theme); - } else { - mColorState = state; - } - + private ColorDrawable(ColorState state) { + mColorState = state; 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 9ae788c..bec1d38 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -917,6 +917,20 @@ public abstract class Drawable { } /** + * Clears the mutated state, allowing this drawable to be cached and + * mutated again. + * <p> + * This is hidden because only framework drawables can be cached, so + * custom drawables don't need to support constant state, mutate(), or + * clearMutated(). + * + * @hide + */ + public void clearMutated() { + // Default implementation is no-op. + } + + /** * Create a drawable from an inputstream */ public static Drawable createFromStream(InputStream is, String srcName) { @@ -1202,7 +1216,7 @@ public abstract class Drawable { * implemented for drawables that can have a theme applied. */ public Drawable newDrawable(Resources res, Theme theme) { - return newDrawable(); + return newDrawable(null); } /** diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 4a719fe..a903288 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -574,6 +574,15 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mDrawableContainerState.clearMutated(); + mMutated = false; + } + + /** * A ConstantState that can contain several {@link Drawable}s. * * This class was made public to enable testing, and its visibility may change in a future @@ -583,8 +592,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { final DrawableContainer mOwner; final Resources mRes; - Theme mTheme; - SparseArray<ConstantStateFuture> mDrawableFutures; int mChangingConfigurations; @@ -792,17 +799,17 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } final void applyTheme(Theme theme) { - // No need to call createAllFutures, since future drawables will - // apply the theme when they are prepared. - final int N = mNumChildren; - final Drawable[] drawables = mDrawables; - for (int i = 0; i < N; i++) { - if (drawables[i] != null) { - drawables[i].applyTheme(theme); + if (theme != null) { + createAllFutures(); + + final int N = mNumChildren; + final Drawable[] drawables = mDrawables; + for (int i = 0; i < N; i++) { + if (drawables[i] != null && drawables[i].canApplyTheme()) { + drawables[i].applyTheme(theme); + } } } - - mTheme = theme; } @Override @@ -840,6 +847,18 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mMutated = true; } + final void clearMutated() { + final int N = mNumChildren; + final Drawable[] drawables = mDrawables; + for (int i = 0; i < N; i++) { + if (drawables[i] != null) { + drawables[i].clearMutated(); + } + } + + mMutated = false; + } + /** * A boolean value indicating whether to use the maximum padding value * of all frames in the set (false), or to use the padding value of the @@ -1047,10 +1066,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { final Drawable result; if (state.mRes == null) { result = mConstantState.newDrawable(); - } else if (state.mTheme == null) { - result = mConstantState.newDrawable(state.mRes); } else { - result = mConstantState.newDrawable(state.mRes, state.mTheme); + result = mConstantState.newDrawable(state.mRes); } result.setLayoutDirection(state.mLayoutDirection); result.setCallback(state.mOwner); diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index cd6297b..eff5a3d 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -29,6 +29,8 @@ import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.graphics.RadialGradient; import android.graphics.Rect; import android.graphics.RectF; @@ -134,6 +136,7 @@ public class GradientDrawable extends Drawable { private Rect mPadding; private Paint mStrokePaint; // optional, set by the caller private ColorFilter mColorFilter; // optional, set by the caller + private PorterDuffColorFilter mTintFilter; private int mAlpha = 0xFF; // modified by the caller private final Path mPath = new Path(); @@ -171,7 +174,7 @@ public class GradientDrawable extends Drawable { } public GradientDrawable() { - this(new GradientState(Orientation.TOP_BOTTOM, null), null); + this(new GradientState(Orientation.TOP_BOTTOM, null)); } /** @@ -179,7 +182,7 @@ public class GradientDrawable extends Drawable { * of colors for the gradient. */ public GradientDrawable(Orientation orientation, int[] colors) { - this(new GradientState(orientation, colors), null); + this(new GradientState(orientation, colors)); } @Override @@ -523,13 +526,15 @@ public class GradientDrawable extends Drawable { mStrokePaint.getStrokeWidth() > 0; final boolean haveFill = currFillAlpha > 0; final GradientState st = mGradientState; + final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter; + /* we need a layer iff we're drawing both a fill and stroke, and the stroke is non-opaque, and our shapetype actually supports fill+stroke. Otherwise we can just draw the stroke (if any) on top of the fill (if any) without worrying about blending artifacts. */ - final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && - currStrokeAlpha < 255 && (mAlpha < 255 || mColorFilter != null); + final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && + currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null); /* Drawing with a layer is slower than direct drawing, but it allows us to apply paint effects like alpha and colorfilter to @@ -544,7 +549,7 @@ public class GradientDrawable extends Drawable { } mLayerPaint.setDither(st.mDither); mLayerPaint.setAlpha(mAlpha); - mLayerPaint.setColorFilter(mColorFilter); + mLayerPaint.setColorFilter(colorFilter); float rad = mStrokePaint.getStrokeWidth(); canvas.saveLayer(mRect.left - rad, mRect.top - rad, @@ -561,14 +566,14 @@ public class GradientDrawable extends Drawable { */ mFillPaint.setAlpha(currFillAlpha); mFillPaint.setDither(st.mDither); - mFillPaint.setColorFilter(mColorFilter); - if (mColorFilter != null && st.mColorStateList == null) { + mFillPaint.setColorFilter(colorFilter); + if (colorFilter != null && st.mColorStateList == null) { mFillPaint.setColor(mAlpha << 24); } if (haveStroke) { mStrokePaint.setAlpha(currStrokeAlpha); mStrokePaint.setDither(st.mDither); - mStrokePaint.setColorFilter(mColorFilter); + mStrokePaint.setColorFilter(colorFilter); } } @@ -593,7 +598,7 @@ public class GradientDrawable extends Drawable { canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); } } else { - if (mFillPaint.getColor() != 0 || mColorFilter != null || + if (mFillPaint.getColor() != 0 || colorFilter != null || mFillPaint.getShader() != null) { canvas.drawRect(mRect, mFillPaint); } @@ -768,6 +773,11 @@ public class GradientDrawable extends Drawable { } } + if (s.mTint != null && s.mTintMode != null) { + mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode); + invalidateSelf = true; + } + if (invalidateSelf) { invalidateSelf(); return true; @@ -781,7 +791,8 @@ public class GradientDrawable extends Drawable { final GradientState s = mGradientState; return super.isStateful() || (s.mColorStateList != null && s.mColorStateList.isStateful()) - || (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful()); + || (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful()) + || (s.mTint != null && s.mTint.isStateful()); } @Override @@ -824,6 +835,20 @@ public class GradientDrawable extends Drawable { } @Override + public void setTintList(ColorStateList tint) { + mGradientState.mTint = tint; + mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode); + invalidateSelf(); + } + + @Override + public void setTintMode(PorterDuff.Mode tintMode) { + mGradientState.mTintMode = tintMode; + mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode); + invalidateSelf(); + } + + @Override public int getOpacity() { return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT; @@ -997,13 +1022,16 @@ public class GradientDrawable extends Drawable { super.applyTheme(t); final GradientState state = mGradientState; - if (state == null || state.mThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.GradientDrawable); - updateStateFromTypedArray(a); - a.recycle(); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes( + state.mThemeAttrs, R.styleable.GradientDrawable); + updateStateFromTypedArray(a); + a.recycle(); + } applyThemeChildElements(t); @@ -1045,15 +1073,23 @@ public class GradientDrawable extends Drawable { state.mUseLevelForShape = a.getBoolean( R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape); } + + final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1); + if (tintMode != -1) { + state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN); + } + + final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint); + if (tint != null) { + state.mTint = tint; + } + + mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); } @Override public boolean canApplyTheme() { - final GradientState st = mGradientState; - return st != null && (st.mThemeAttrs != null || st.mAttrSize != null - || st.mAttrGradient != null || st.mAttrSolid != null - || st.mAttrStroke != null || st.mAttrCorners != null - || st.mAttrPadding != null); + return super.canApplyTheme() || mGradientState != null && mGradientState.canApplyTheme(); } private void applyThemeChildElements(Theme t) { @@ -1479,6 +1515,14 @@ public class GradientDrawable extends Drawable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + final static class GradientState extends ConstantState { public int mChangingConfigurations; public int mShape = RECTANGLE; @@ -1514,6 +1558,9 @@ public class GradientDrawable extends Drawable { private boolean mOpaqueOverBounds; private boolean mOpaqueOverShape; + ColorStateList mTint = null; + PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; + int[] mThemeAttrs; int[] mAttrSize; int[] mAttrGradient; @@ -1566,6 +1613,8 @@ public class GradientDrawable extends Drawable { mUseLevelForShape = state.mUseLevelForShape; mOpaqueOverBounds = state.mOpaqueOverBounds; mOpaqueOverShape = state.mOpaqueOverShape; + mTint = state.mTint; + mTintMode = state.mTintMode; mThemeAttrs = state.mThemeAttrs; mAttrSize = state.mAttrSize; mAttrGradient = state.mAttrGradient; @@ -1577,22 +1626,19 @@ public class GradientDrawable extends Drawable { @Override public boolean canApplyTheme() { - return mThemeAttrs != null; + return mThemeAttrs != null || mAttrSize != null || mAttrGradient != null + || mAttrSolid != null || mAttrStroke != null || mAttrCorners != null + || mAttrPadding != null; } @Override public Drawable newDrawable() { - return new GradientDrawable(this, null); + return new GradientDrawable(this); } @Override public Drawable newDrawable(Resources res) { - return new GradientDrawable(this, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new GradientDrawable(this, theme); + return new GradientDrawable(this); } @Override @@ -1696,18 +1742,11 @@ public class GradientDrawable extends Drawable { * The resulting drawable is guaranteed to have a new constant state. * * @param state Constant state from which the drawable inherits - * @param theme Theme to apply to the drawable */ - private GradientDrawable(GradientState state, Theme theme) { - if (theme != null && state.canApplyTheme()) { - // If we need to apply a theme, implicitly mutate. - mGradientState = new GradientState(state); - applyTheme(theme); - } else { - mGradientState = state; - } + private GradientDrawable(GradientState state) { + mGradientState = state; - initializeWithState(state); + initializeWithState(mGradientState); mGradientIsDirty = true; mMutated = false; diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index 961d160..f1800e5 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -170,24 +170,30 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { super.applyTheme(t); final InsetState state = mInsetState; - if (state == null || state.mThemeAttrs == null) { + if (state == null) { return; } - final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.InsetDrawable); - try { - updateStateFromTypedArray(a); - verifyRequiredAttributes(a); - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } finally { - a.recycle(); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.InsetDrawable); + try { + updateStateFromTypedArray(a); + verifyRequiredAttributes(a); + } catch (XmlPullParserException e) { + throw new RuntimeException(e); + } finally { + a.recycle(); + } + } + + if (state.mDrawable != null && state.mDrawable.canApplyTheme()) { + state.mDrawable.applyTheme(t); } } @Override public boolean canApplyTheme() { - return mInsetState != null && mInsetState.mThemeAttrs != null; + return super.canApplyTheme() || mInsetState != null && mInsetState.canApplyTheme(); } @Override @@ -339,12 +345,14 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { @Override public int getIntrinsicWidth() { - return mInsetState.mDrawable.getIntrinsicWidth(); + return mInsetState.mDrawable.getIntrinsicWidth() + + mInsetState.mInsetLeft + mInsetState.mInsetRight; } @Override public int getIntrinsicHeight() { - return mInsetState.mDrawable.getIntrinsicHeight(); + return mInsetState.mDrawable.getIntrinsicHeight() + + mInsetState.mInsetTop + mInsetState.mInsetBottom; } @Override @@ -371,6 +379,15 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { } /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mInsetState.mDrawable.clearMutated(); + mMutated = false; + } + + /** * Returns the drawable wrapped by this InsetDrawable. May be null. */ public Drawable getDrawable() { @@ -427,6 +444,12 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { return mChangingConfigurations; } + @Override + public boolean canApplyTheme() { + return super.canApplyTheme() || mThemeAttrs != null + || mDrawable != null && mDrawable.canApplyTheme(); + } + boolean canConstantState() { if (!mCheckedConstantState) { mCanConstantState = mDrawable.getConstantState() != null; diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 001ed88..5107e10 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -100,10 +100,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { * @param state The constant drawable state. */ LayerDrawable(Drawable[] layers, LayerState state) { - this(state, null, null); - int length = layers.length; - ChildDrawable[] r = new ChildDrawable[length]; + this(state, null); + final int length = layers.length; + final ChildDrawable[] r = new ChildDrawable[length]; for (int i = 0; i < length; i++) { r[i] = new ChildDrawable(); r[i].mDrawable = layers[i]; @@ -117,18 +117,14 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } LayerDrawable() { - this((LayerState) null, null, null); + this((LayerState) null, null); } - LayerDrawable(LayerState state, Resources res, Theme theme) { - final LayerState as = createConstantState(state, res); - mLayerState = as; - if (as.mNum > 0) { + LayerDrawable(LayerState state, Resources res) { + mLayerState = createConstantState(state, res); + if (mLayerState.mNum > 0) { ensurePadding(); } - if (theme != null && canApplyTheme()) { - applyTheme(theme); - } } LayerState createConstantState(LayerState state, Resources res) { @@ -256,8 +252,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { a.recycle(); } - final ChildDrawable[] array = mLayerState.mChildren; - final int N = mLayerState.mNum; + final ChildDrawable[] array = state.mChildren; + final int N = state.mNum; for (int i = 0; i < N; i++) { final ChildDrawable layer = array[i]; if (layer.mThemeAttrs != null) { @@ -279,25 +275,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { @Override public boolean canApplyTheme() { - final LayerState state = mLayerState; - if (state == null) { - return false; - } - - if (state.mThemeAttrs != null) { - return true; - } - - final ChildDrawable[] array = state.mChildren; - final int N = state.mNum; - for (int i = 0; i < N; i++) { - final ChildDrawable layer = array[i]; - if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) { - return true; - } - } - - return false; + return super.canApplyTheme() || mLayerState != null && mLayerState.canApplyTheme(); } /** @@ -940,6 +918,19 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.clearMutated(); + } + mMutated = false; + } + /** @hide */ @Override public void setLayoutDirection(int layoutDirection) { @@ -1029,22 +1020,30 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { @Override public boolean canApplyTheme() { - return mThemeAttrs != null; + if (mThemeAttrs != null) { + return true; + } + + final ChildDrawable[] array = mChildren; + final int N = mNum; + for (int i = 0; i < N; i++) { + final ChildDrawable layer = array[i]; + if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) { + return true; + } + } + + return false; } @Override public Drawable newDrawable() { - return new LayerDrawable(this, null, null); + return new LayerDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new LayerDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new LayerDrawable(this, res, theme); + return new LayerDrawable(this, res); } @Override diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java index bc1c61d..9e918f6 100644 --- a/graphics/java/android/graphics/drawable/LevelListDrawable.java +++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java @@ -153,6 +153,14 @@ public class LevelListDrawable extends DrawableContainer { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + private final static class LevelListState extends DrawableContainerState { private int[] mLows; private int[] mHighs; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 6c62ccf..d821224 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -90,7 +90,7 @@ public class NinePatchDrawable extends Drawable { */ @Deprecated public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) { - this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), null, null); + this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), null); } /** @@ -99,7 +99,7 @@ public class NinePatchDrawable extends Drawable { */ public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk, Rect padding, String srcName) { - this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res, null); + this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res); mNinePatchState.mTargetDensity = mTargetDensity; } @@ -112,7 +112,7 @@ public class NinePatchDrawable extends Drawable { public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk, Rect padding, Rect opticalInsets, String srcName) { this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding, opticalInsets), - res, null); + res); mNinePatchState.mTargetDensity = mTargetDensity; } @@ -123,7 +123,7 @@ public class NinePatchDrawable extends Drawable { */ @Deprecated public NinePatchDrawable(NinePatch patch) { - this(new NinePatchState(patch, new Rect()), null, null); + this(new NinePatchState(patch, new Rect()), null); } /** @@ -131,7 +131,7 @@ public class NinePatchDrawable extends Drawable { * based on the display metrics of the resources. */ public NinePatchDrawable(Resources res, NinePatch patch) { - this(new NinePatchState(patch, new Rect()), res, null); + this(new NinePatchState(patch, new Rect()), res); mNinePatchState.mTargetDensity = mTargetDensity; } @@ -563,6 +563,14 @@ public class NinePatchDrawable extends Drawable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + @Override protected boolean onStateChange(int[] stateSet) { final NinePatchState state = mNinePatchState; @@ -646,17 +654,12 @@ public class NinePatchDrawable extends Drawable { @Override public Drawable newDrawable() { - return new NinePatchDrawable(this, null, null); + return new NinePatchDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new NinePatchDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new NinePatchDrawable(this, res, theme); + return new NinePatchDrawable(this, res); } @Override @@ -669,16 +672,10 @@ public class NinePatchDrawable extends Drawable { * The one constructor to rule them all. This is called by all public * constructors to set the state and initialize local properties. */ - private NinePatchDrawable(NinePatchState state, Resources res, Theme theme) { - if (theme != null && state.canApplyTheme()) { - // If we need to apply a theme, implicitly mutate. - mNinePatchState = new NinePatchState(state); - applyTheme(theme); - } else { - mNinePatchState = state; - } + private NinePatchDrawable(NinePatchState state, Resources res) { + mNinePatchState = state; - initializeWithState(state, res); + initializeWithState(mNinePatchState, res); } /** diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java index faa89bf..21d865f 100644 --- a/graphics/java/android/graphics/drawable/RippleBackground.java +++ b/graphics/java/android/graphics/drawable/RippleBackground.java @@ -43,10 +43,12 @@ class RippleBackground { private static final float WAVE_OPACITY_DECAY_VELOCITY = 3.0f / GLOBAL_SPEED; private static final float WAVE_OUTER_OPACITY_EXIT_VELOCITY_MAX = 4.5f * GLOBAL_SPEED; private static final float WAVE_OUTER_OPACITY_EXIT_VELOCITY_MIN = 1.5f * GLOBAL_SPEED; - private static final float WAVE_OUTER_OPACITY_ENTER_VELOCITY = 10.0f * GLOBAL_SPEED; private static final float WAVE_OUTER_SIZE_INFLUENCE_MAX = 200f; private static final float WAVE_OUTER_SIZE_INFLUENCE_MIN = 40f; + private static final int ENTER_DURATION = 667; + private static final int ENTER_DURATION_FAST = 100; + // Hardware animators. private final ArrayList<RenderNodeAnimator> mRunningAnimations = new ArrayList<RenderNodeAnimator>(); @@ -224,21 +226,20 @@ class RippleBackground { /** * Starts the enter animation. */ - public void enter() { + public void enter(boolean fast) { cancel(); - final int outerDuration = (int) (1000 * 1.0f / WAVE_OUTER_OPACITY_ENTER_VELOCITY); - final ObjectAnimator outer = ObjectAnimator.ofFloat(this, "outerOpacity", 0, 1); - outer.setAutoCancel(true); - outer.setDuration(outerDuration); - outer.setInterpolator(LINEAR_INTERPOLATOR); + final ObjectAnimator opacity = ObjectAnimator.ofFloat(this, "outerOpacity", 0, 1); + opacity.setAutoCancel(true); + opacity.setDuration(fast ? ENTER_DURATION_FAST : ENTER_DURATION); + opacity.setInterpolator(LINEAR_INTERPOLATOR); - mAnimOuterOpacity = outer; + mAnimOuterOpacity = opacity; // Enter animations always run on the UI thread, since it's unlikely // that anything interesting is happening until the user lifts their // finger. - outer.start(); + opacity.start(); } /** diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index c7aa98e..316139b 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -167,7 +167,7 @@ public class RippleDrawable extends LayerDrawable { * Constructor used for drawable inflation. */ RippleDrawable() { - this(new RippleState(null, null, null), null, null); + this(new RippleState(null, null, null), null); } /** @@ -180,7 +180,7 @@ public class RippleDrawable extends LayerDrawable { */ public RippleDrawable(@NonNull ColorStateList color, @Nullable Drawable content, @Nullable Drawable mask) { - this(new RippleState(null, null, null), null, null); + this(new RippleState(null, null, null), null); if (color == null) { throw new IllegalArgumentException("RippleDrawable requires a non-null color"); @@ -280,7 +280,7 @@ public class RippleDrawable extends LayerDrawable { } setRippleActive(enabled && pressed); - setBackgroundActive(focused || (enabled && pressed)); + setBackgroundActive(focused || (enabled && pressed), focused); return changed; } @@ -296,11 +296,11 @@ public class RippleDrawable extends LayerDrawable { } } - private void setBackgroundActive(boolean active) { + private void setBackgroundActive(boolean active, boolean focused) { if (mBackgroundActive != active) { mBackgroundActive = active; if (active) { - tryBackgroundEnter(); + tryBackgroundEnter(focused); } else { tryBackgroundExit(); } @@ -333,8 +333,11 @@ public class RippleDrawable extends LayerDrawable { } if (mBackgroundActive) { - tryBackgroundEnter(); + tryBackgroundEnter(false); } + + // Skip animations, just show the correct final states. + jumpToCurrentState(); } return changed; @@ -470,7 +473,7 @@ public class RippleDrawable extends LayerDrawable { @Override public boolean canApplyTheme() { - return super.canApplyTheme() || mState != null && mState.mTouchThemeAttrs != null; + return super.canApplyTheme() || mState != null && mState.canApplyTheme(); } @Override @@ -489,14 +492,14 @@ public class RippleDrawable extends LayerDrawable { /** * Creates an active hotspot at the specified location. */ - private void tryBackgroundEnter() { + private void tryBackgroundEnter(boolean focused) { if (mBackground == null) { mBackground = new RippleBackground(this, mHotspotBounds); } final int color = mState.mColor.getColorForState(getState(), Color.TRANSPARENT); mBackground.setup(mState.mMaxRadius, color, mDensity); - mBackground.enter(); + mBackground.enter(focused); } private void tryBackgroundExit() { @@ -715,10 +718,12 @@ public class RippleDrawable extends LayerDrawable { final ChildDrawable[] array = mLayerState.mChildren; final int count = mLayerState.mNum; - // We don't need a layer if we don't expect to draw any ripples, we have - // an explicit mask, or if the non-mask content is all opaque. + // We don't need a layer if we don't expect to draw any ripples or + // a background, we have an explicit mask, or if the non-mask content + // is all opaque. boolean needsLayer = false; - if ((mExitingRipplesCount > 0 || mBackground != null) && mMask == null) { + if ((mExitingRipplesCount > 0 || (mBackground != null && mBackground.shouldDraw())) + && mMask == null) { for (int i = 0; i < count; i++) { if (array[i].mId != R.id.mask && array[i].mDrawable.getOpacity() != PixelFormat.OPAQUE) { @@ -924,17 +929,12 @@ public class RippleDrawable extends LayerDrawable { @Override public Drawable newDrawable() { - return new RippleDrawable(this, null, null); + return new RippleDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new RippleDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new RippleDrawable(this, res, theme); + return new RippleDrawable(this, res); } } @@ -968,37 +968,18 @@ public class RippleDrawable extends LayerDrawable { return mState.mMaxRadius; } - private RippleDrawable(RippleState state, Resources res, Theme theme) { - boolean needsTheme = false; + private RippleDrawable(RippleState state, Resources res) { + mState = new RippleState(state, this, res); + mLayerState = mState; - final RippleState ns; - if (theme != null && state != null && state.canApplyTheme()) { - ns = new RippleState(state, this, res); - needsTheme = true; - } else if (state == null) { - ns = new RippleState(null, this, res); - } else { - // We always need a new state since child drawables contain local - // state but live within the parent's constant state. - // TODO: Move child drawables into local state. - ns = new RippleState(state, this, res); + if (mState.mNum > 0) { + ensurePadding(); } if (res != null) { mDensity = res.getDisplayMetrics().density; } - mState = ns; - mLayerState = ns; - - if (ns.mNum > 0) { - ensurePadding(); - } - - if (needsTheme) { - applyTheme(theme); - } - initializeFromState(); } diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java index 55c9637..3f75bc3 100644 --- a/graphics/java/android/graphics/drawable/RotateDrawable.java +++ b/graphics/java/android/graphics/drawable/RotateDrawable.java @@ -16,6 +16,8 @@ package android.graphics.drawable; +import com.android.internal.R; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -476,6 +478,26 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { } @Override + public void applyTheme(Theme t) { + super.applyTheme(t); + + final RotateState state = mState; + if (state == null) { + return; + } + + if (state.mDrawable != null) { + state.mDrawable.applyTheme(t); + } + } + + @Override + public boolean canApplyTheme() { + final RotateState state = mState; + return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme(); + } + + @Override public Drawable mutate() { if (!mMutated && super.mutate() == this) { mState.mDrawable.mutate(); @@ -485,6 +507,15 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { } /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mState.mDrawable.clearMutated(); + mMutated = false; + } + + /** * Represents the state of a rotation for a given drawable. The same * rotate drawable can be invoked with different states to drive several * rotations at the same time. diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java index b990249..9a5b8fb 100644 --- a/graphics/java/android/graphics/drawable/ScaleDrawable.java +++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java @@ -128,6 +128,26 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback { } } + @Override + public void applyTheme(Theme t) { + super.applyTheme(t); + + final ScaleState state = mScaleState; + if (state == null) { + return; + } + + if (state.mDrawable != null) { + state.mDrawable.applyTheme(t); + } + } + + @Override + public boolean canApplyTheme() { + final ScaleState state = mScaleState; + return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme(); + } + // overrides from Drawable.Callback public void invalidateDrawable(Drawable who) { @@ -276,6 +296,15 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mScaleState.mDrawable.clearMutated(); + mMutated = false; + } + final static class ScaleState extends ConstantState { Drawable mDrawable; int mChangingConfigurations; diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index bd69d76..a3d8c92 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -76,7 +76,7 @@ public class ShapeDrawable extends Drawable { * ShapeDrawable constructor. */ public ShapeDrawable() { - this(new ShapeState(null), null, null); + this(new ShapeState(null), null); } /** @@ -85,7 +85,7 @@ public class ShapeDrawable extends Drawable { * @param s the Shape that this ShapeDrawable should be */ public ShapeDrawable(Shape s) { - this(new ShapeState(null), null, null); + this(new ShapeState(null), null); mShapeState.mShape = s; } @@ -508,6 +508,14 @@ public class ShapeDrawable extends Drawable { } /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + + /** * Defines the intrinsic properties of this ShapeDrawable's Shape. */ final static class ShapeState extends ConstantState { @@ -547,17 +555,12 @@ public class ShapeDrawable extends Drawable { @Override public Drawable newDrawable() { - return new ShapeDrawable(this, null, null); + return new ShapeDrawable(this, null); } @Override public Drawable newDrawable(Resources res) { - return new ShapeDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new ShapeDrawable(this, res, theme); + return new ShapeDrawable(this, res); } @Override @@ -570,13 +573,8 @@ public class ShapeDrawable extends Drawable { * The one constructor to rule them all. This is called by all public * constructors to set the state and initialize local properties. */ - private ShapeDrawable(ShapeState state, Resources res, Theme theme) { - if (theme != null && state.canApplyTheme()) { - mShapeState = new ShapeState(state); - applyTheme(theme); - } else { - mShapeState = state; - } + private ShapeDrawable(ShapeState state, Resources res) { + mShapeState = state; initializeWithState(state, res); } diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index 2eb8a80..a299b3c 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -263,6 +263,14 @@ public class StateListDrawable extends DrawableContainer { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + /** @hide */ @Override public void setLayoutDirection(int layoutDirection) { @@ -280,7 +288,16 @@ public class StateListDrawable extends DrawableContainer { super(orig, owner, res); if (orig != null) { - mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length); + // Perform a deep copy. + final int[][] sets = orig.mStateSets; + final int count = sets.length; + mStateSets = new int[count][]; + for (int i = 0; i < count; i++) { + final int[] set = sets[i]; + if (set != null) { + mStateSets[i] = set.clone(); + } + } } else { mStateSets = new int[getCapacity()][]; } @@ -322,6 +339,13 @@ public class StateListDrawable extends DrawableContainer { } } + @Override + public void applyTheme(Theme theme) { + super.applyTheme(theme); + + onStateChange(getState()); + } + void setConstantState(StateListState state) { super.setConstantState(state); diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java index 4380ca4..e5c235e 100644 --- a/graphics/java/android/graphics/drawable/TransitionDrawable.java +++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java @@ -17,7 +17,6 @@ package android.graphics.drawable; import android.content.res.Resources; -import android.content.res.Resources.Theme; import android.graphics.Canvas; import android.os.SystemClock; @@ -86,11 +85,11 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba * @see #TransitionDrawable(Drawable[]) */ TransitionDrawable() { - this(new TransitionState(null, null, null), null, null); + this(new TransitionState(null, null, null), (Resources) null); } - private TransitionDrawable(TransitionState state, Resources res, Theme theme) { - super(state, res, theme); + private TransitionDrawable(TransitionState state, Resources res) { + super(state, res); } private TransitionDrawable(TransitionState state, Drawable[] layers) { @@ -245,24 +244,18 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba } static class TransitionState extends LayerState { - TransitionState(TransitionState orig, TransitionDrawable owner, - Resources res) { + TransitionState(TransitionState orig, TransitionDrawable owner, Resources res) { super(orig, owner, res); } @Override public Drawable newDrawable() { - return new TransitionDrawable(this, null, null); + return new TransitionDrawable(this, (Resources) null); } @Override public Drawable newDrawable(Resources res) { - return new TransitionDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new TransitionDrawable(this, res, theme); + return new TransitionDrawable(this, res); } @Override diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index db0c94f..848fc53 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.annotation.NonNull; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -212,15 +213,8 @@ public class VectorDrawable extends Drawable { mVectorState = new VectorDrawableState(); } - private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) { - if (theme != null && state.canApplyTheme()) { - // If we need to apply a theme, implicitly mutate. - mVectorState = new VectorDrawableState(state); - applyTheme(theme); - } else { - mVectorState = state; - } - + private VectorDrawable(@NonNull VectorDrawableState state) { + mVectorState = state; mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); } @@ -233,6 +227,14 @@ public class VectorDrawable extends Drawable { return this; } + /** + * @hide + */ + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + Object getTargetByName(String name) { return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); } @@ -758,17 +760,12 @@ public class VectorDrawable extends Drawable { @Override public Drawable newDrawable() { - return new VectorDrawable(this, null, null); + return new VectorDrawable(this); } @Override public Drawable newDrawable(Resources res) { - return new VectorDrawable(this, res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new VectorDrawable(this, res, theme); + return new VectorDrawable(this); } @Override |