summaryrefslogtreecommitdiffstats
path: root/graphics/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java/android')
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java29
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java8
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java66
-rw-r--r--graphics/java/android/graphics/drawable/AnimationDrawable.java8
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java41
-rw-r--r--graphics/java/android/graphics/drawable/ClipDrawable.java40
-rw-r--r--graphics/java/android/graphics/drawable/ColorDrawable.java27
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java16
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java45
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java113
-rw-r--r--graphics/java/android/graphics/drawable/InsetDrawable.java47
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java79
-rw-r--r--graphics/java/android/graphics/drawable/LevelListDrawable.java8
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java39
-rw-r--r--graphics/java/android/graphics/drawable/RippleBackground.java19
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java67
-rw-r--r--graphics/java/android/graphics/drawable/RotateDrawable.java31
-rw-r--r--graphics/java/android/graphics/drawable/ScaleDrawable.java29
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java30
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java26
-rw-r--r--graphics/java/android/graphics/drawable/TransitionDrawable.java19
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java29
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