summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java160
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java72
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java11
-rw-r--r--graphics/java/android/graphics/drawable/AnimationDrawable.java58
-rw-r--r--graphics/java/android/graphics/drawable/ClipDrawable.java161
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java8
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java4
-rw-r--r--graphics/java/android/graphics/drawable/InsetDrawable.java159
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java4
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/RotateDrawable.java187
-rw-r--r--graphics/java/android/graphics/drawable/ScaleDrawable.java204
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java66
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java6
14 files changed, 677 insertions, 425 deletions
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index c2e93a7..d2799e1 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -16,6 +16,8 @@
package android.graphics.drawable;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.ColorFilter;
@@ -41,6 +43,7 @@ import com.android.internal.R;
*/
public class AnimatedRotateDrawable extends Drawable implements Drawable.Callback, Runnable,
Animatable {
+ private static final String TAG = "AnimatedRotateDrawable";
private AnimatedRotateState mState;
private boolean mMutated;
@@ -186,6 +189,11 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
}
@Override
+ public boolean canApplyTheme() {
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
+ }
+
+ @Override
public void invalidateDrawable(Drawable who) {
final Callback callback = getCallback();
if (callback != null) {
@@ -254,83 +262,113 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
}
@Override
- public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
+ public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
+ @NonNull AttributeSet attrs, @Nullable Theme theme)
throws XmlPullParserException, IOException {
-
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.AnimatedRotateDrawable);
-
super.inflateWithAttributes(r, parser, a, R.styleable.AnimatedRotateDrawable_visible);
+ updateStateFromTypedArray(a);
+ a.recycle();
- TypedValue tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotX);
- final boolean pivotXRel = tv.type == TypedValue.TYPE_FRACTION;
- final float pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+ inflateChildElements(r, parser, attrs, theme);
- tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotY);
- final boolean pivotYRel = tv.type == TypedValue.TYPE_FRACTION;
- final float pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+ init();
+ }
- setFramesCount(a.getInt(R.styleable.AnimatedRotateDrawable_framesCount, 12));
- setFramesDuration(a.getInt(R.styleable.AnimatedRotateDrawable_frameDuration, 150));
+ @Override
+ public void applyTheme(@Nullable Theme t) {
+ super.applyTheme(t);
- final int res = a.getResourceId(R.styleable.AnimatedRotateDrawable_drawable, 0);
- Drawable drawable = null;
- if (res > 0) {
- drawable = r.getDrawable(res, theme);
+ final AnimatedRotateState state = mState;
+ if (state == null) {
+ return;
}
- a.recycle();
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
- (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-
- if (type != XmlPullParser.START_TAG) {
- continue;
+ if (state.mThemeAttrs != null) {
+ final TypedArray a = t.resolveAttributes(
+ state.mThemeAttrs, R.styleable.AnimatedRotateDrawable);
+ try {
+ updateStateFromTypedArray(a);
+ verifyRequiredAttributes(a);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ } finally {
+ a.recycle();
}
+ }
- if ((drawable = Drawable.createFromXmlInner(r, parser, attrs, theme)) == null) {
- Log.w("drawable", "Bad element under <animated-rotate>: "
- + parser .getName());
- }
+ if (state.mDrawable != null && state.mDrawable.canApplyTheme()) {
+ state.mDrawable.applyTheme(t);
}
- if (drawable == null) {
- Log.w("drawable", "No drawable specified for <animated-rotate>");
+ init();
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) {
+ final AnimatedRotateState state = mState;
+
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
+
+ // Extract the theme attributes, if any.
+ state.mThemeAttrs = a.extractThemeAttrs();
+
+ if (a.hasValue(R.styleable.AnimatedRotateDrawable_pivotX)) {
+ final TypedValue tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotX);
+ state.mPivotXRel = tv.type == TypedValue.TYPE_FRACTION;
+ state.mPivotX = state.mPivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
}
- final AnimatedRotateState rotateState = mState;
- rotateState.mDrawable = drawable;
- rotateState.mPivotXRel = pivotXRel;
- rotateState.mPivotX = pivotX;
- rotateState.mPivotYRel = pivotYRel;
- rotateState.mPivotY = pivotY;
+ if (a.hasValue(R.styleable.AnimatedRotateDrawable_pivotY)) {
+ final TypedValue tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotY);
+ state.mPivotYRel = tv.type == TypedValue.TYPE_FRACTION;
+ state.mPivotY = state.mPivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+ }
- init();
+ setFramesCount(a.getInt(
+ R.styleable.AnimatedRotateDrawable_framesCount, state.mFramesCount));
+ setFramesDuration(a.getInt(
+ R.styleable.AnimatedRotateDrawable_frameDuration, state.mFrameDuration));
- if (drawable != null) {
- drawable.setCallback(this);
+ final Drawable dr = a.getDrawable(R.styleable.AnimatedRotateDrawable_drawable);
+ if (dr != null) {
+ state.mDrawable = dr;
+ dr.setCallback(this);
}
}
- @Override
- public void applyTheme(Theme t) {
- super.applyTheme(t);
-
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
final AnimatedRotateState state = mState;
- if (state == null) {
- return;
+
+ Drawable dr = null;
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ if ((dr = Drawable.createFromXmlInner(r, parser, attrs, theme)) == null) {
+ Log.w(TAG, "Bad element under <animated-rotate>: " + parser.getName());
+ }
}
- if (state.mDrawable != null) {
- state.mDrawable.applyTheme(t);
+ if (dr != null) {
+ state.mDrawable = dr;
+ dr.setCallback(this);
}
}
- @Override
- public boolean canApplyTheme() {
- final AnimatedRotateState state = mState;
- return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme();
+ private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
+ // If we're not waiting on a theme, verify required attributes.
+ if (mState.mDrawable == null && (mState.mThemeAttrs == null
+ || mState.mThemeAttrs[R.styleable.AnimatedRotateDrawable_drawable] == 0)) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + ": <animated-rotate> tag requires a 'drawable' attribute or "
+ + "child tag defining a drawable");
+ }
}
public void setFramesCount(int framesCount) {
@@ -362,15 +400,16 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
final static class AnimatedRotateState extends Drawable.ConstantState {
Drawable mDrawable;
+ int[] mThemeAttrs;
int mChangingConfigurations;
- boolean mPivotXRel;
- float mPivotX;
- boolean mPivotYRel;
- float mPivotY;
- int mFrameDuration;
- int mFramesCount;
+ boolean mPivotXRel = false;
+ float mPivotX = 0;
+ boolean mPivotYRel = false;
+ float mPivotY = 0;
+ int mFrameDuration = 150;
+ int mFramesCount = 12;
private boolean mCanConstantState;
private boolean mCheckedConstantState;
@@ -387,6 +426,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
mDrawable.setBounds(orig.mDrawable.getBounds());
mDrawable.setLevel(orig.mDrawable.getLevel());
+ mThemeAttrs = orig.mThemeAttrs;
mPivotXRel = orig.mPivotXRel;
mPivotX = orig.mPivotX;
mPivotYRel = orig.mPivotYRel;
@@ -408,6 +448,12 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
}
@Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
public int getChangingConfigurations() {
return mChangingConfigurations;
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 849faec..3b125fd 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -347,24 +347,62 @@ public class AnimatedStateListDrawable extends StateListDrawable {
throws XmlPullParserException, IOException {
final TypedArray a = obtainAttributes(
r, theme, attrs, R.styleable.AnimatedStateListDrawable);
-
super.inflateWithAttributes(r, parser, a, R.styleable.AnimatedStateListDrawable_visible);
+ updateStateFromTypedArray(a);
+ a.recycle();
+
+ inflateChildElements(r, parser, attrs, theme);
- final StateListState stateListState = getStateListState();
- stateListState.setVariablePadding(a.getBoolean(
- R.styleable.AnimatedStateListDrawable_variablePadding, false));
- stateListState.setConstantSize(a.getBoolean(
- R.styleable.AnimatedStateListDrawable_constantSize, false));
- stateListState.setEnterFadeDuration(a.getInt(
- R.styleable.AnimatedStateListDrawable_enterFadeDuration, 0));
- stateListState.setExitFadeDuration(a.getInt(
- R.styleable.AnimatedStateListDrawable_exitFadeDuration, 0));
+ init();
+ }
+
+ @Override
+ public void applyTheme(@Nullable Theme theme) {
+ super.applyTheme(theme);
- setDither(a.getBoolean(R.styleable.AnimatedStateListDrawable_dither, true));
- setAutoMirrored(a.getBoolean(R.styleable.AnimatedStateListDrawable_autoMirrored, false));
+ final AnimatedStateListState state = mState;
+ if (state == null || !state.canApplyTheme()) {
+ return;
+ }
+ final TypedArray a = theme.resolveAttributes(
+ state.mAnimThemeAttrs, R.styleable.AnimatedRotateDrawable);
+ updateStateFromTypedArray(a);
a.recycle();
+ init();
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) {
+ final AnimatedStateListState state = mState;
+
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
+
+ // Extract the theme attributes, if any.
+ state.mAnimThemeAttrs = a.extractThemeAttrs();
+
+ state.setVariablePadding(a.getBoolean(
+ R.styleable.AnimatedStateListDrawable_variablePadding, state.mVariablePadding));
+ state.setConstantSize(a.getBoolean(
+ R.styleable.AnimatedStateListDrawable_constantSize, state.mConstantSize));
+ state.setEnterFadeDuration(a.getInt(
+ R.styleable.AnimatedStateListDrawable_enterFadeDuration, state.mEnterFadeDuration));
+ state.setExitFadeDuration(a.getInt(
+ R.styleable.AnimatedStateListDrawable_exitFadeDuration, state.mExitFadeDuration));
+
+ setDither(a.getBoolean(
+ R.styleable.AnimatedStateListDrawable_dither, state.mDither));
+ setAutoMirrored(a.getBoolean(
+ R.styleable.AnimatedStateListDrawable_autoMirrored, state.mAutoMirrored));
+ }
+
+ private void init() {
+ onStateChange(getState());
+ }
+
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
int type;
final int innerDepth = parser.getDepth() + 1;
@@ -386,8 +424,6 @@ public class AnimatedStateListDrawable extends StateListDrawable {
parseTransition(r, parser, attrs, theme);
}
}
-
- onStateChange(getState());
}
private int parseTransition(@NonNull Resources r, @NonNull XmlPullParser parser,
@@ -507,6 +543,8 @@ public class AnimatedStateListDrawable extends StateListDrawable {
private static final int REVERSE_SHIFT = 32;
private static final int REVERSE_MASK = 0x1;
+ int[] mAnimThemeAttrs;
+
final LongSparseLongArray mTransitions;
final SparseIntArray mStateIds;
@@ -515,6 +553,7 @@ public class AnimatedStateListDrawable extends StateListDrawable {
super(orig, owner, res);
if (orig != null) {
+ mAnimThemeAttrs = orig.mAnimThemeAttrs;
mTransitions = orig.mTransitions.clone();
mStateIds = orig.mStateIds.clone();
} else {
@@ -566,6 +605,11 @@ public class AnimatedStateListDrawable extends StateListDrawable {
}
@Override
+ public boolean canApplyTheme() {
+ return mAnimThemeAttrs != null || super.canApplyTheme();
+ }
+
+ @Override
public Drawable newDrawable() {
return new AnimatedStateListDrawable(this, null);
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index a904067..e65dbaf 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -316,9 +316,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mAnimatedVectorState != null
- && mAnimatedVectorState.mVectorDrawable != null
- && mAnimatedVectorState.mVectorDrawable.canApplyTheme();
+ return (mAnimatedVectorState != null && mAnimatedVectorState.canApplyTheme())
+ || super.canApplyTheme();
}
@Override
@@ -374,6 +373,12 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
}
@Override
+ public boolean canApplyTheme() {
+ return (mVectorDrawable != null && mVectorDrawable.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
public Drawable newDrawable() {
return new AnimatedVectorDrawable(this, null);
}
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index c730a20..a8b6c94 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -16,6 +16,8 @@
package android.graphics.drawable;
+import com.android.internal.R;
+
import java.io.IOException;
import org.xmlpull.v1.XmlPullParser;
@@ -271,27 +273,25 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.AnimationDrawable);
+ super.inflateWithAttributes(r, parser, a, R.styleable.AnimationDrawable_visible);
+ updateStateFromTypedArray(a);
+ a.recycle();
- TypedArray a = obtainAttributes(r, theme, attrs,
- com.android.internal.R.styleable.AnimationDrawable);
-
- super.inflateWithAttributes(r, parser, a,
- com.android.internal.R.styleable.AnimationDrawable_visible);
-
- mAnimationState.setVariablePadding(a.getBoolean(
- com.android.internal.R.styleable.AnimationDrawable_variablePadding, false));
-
- mAnimationState.mOneShot = a.getBoolean(
- com.android.internal.R.styleable.AnimationDrawable_oneshot, false);
+ inflateChildElements(r, parser, attrs, theme);
- a.recycle();
+ setFrame(0, true, false);
+ }
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ TypedArray a;
int type;
final int innerDepth = parser.getDepth()+1;
int depth;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT &&
- ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
if (type != XmlPullParser.START_TAG) {
continue;
}
@@ -300,17 +300,15 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
continue;
}
- a = obtainAttributes(
- r, theme, attrs, com.android.internal.R.styleable.AnimationDrawableItem);
- int duration = a.getInt(
- com.android.internal.R.styleable.AnimationDrawableItem_duration, -1);
+ a = obtainAttributes(r, theme, attrs, R.styleable.AnimationDrawableItem);
+
+ final int duration = a.getInt(R.styleable.AnimationDrawableItem_duration, -1);
if (duration < 0) {
- throw new XmlPullParserException(
- parser.getPositionDescription()
+ throw new XmlPullParserException(parser.getPositionDescription()
+ ": <item> tag requires a 'duration' attribute");
}
- int drawableRes = a.getResourceId(
- com.android.internal.R.styleable.AnimationDrawableItem_drawable, 0);
+
+ final int drawableRes = a.getResourceId(R.styleable.AnimationDrawableItem_drawable, 0);
a.recycle();
@@ -322,9 +320,9 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
// Empty
}
if (type != XmlPullParser.START_TAG) {
- throw new XmlPullParserException(parser.getPositionDescription() +
- ": <item> tag requires a 'drawable' attribute or child tag" +
- " defining a drawable");
+ throw new XmlPullParserException(parser.getPositionDescription()
+ + ": <item> tag requires a 'drawable' attribute or child tag"
+ + " defining a drawable");
}
dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
}
@@ -334,8 +332,14 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
dr.setCallback(this);
}
}
+ }
- setFrame(0, true, false);
+ private void updateStateFromTypedArray(TypedArray a) {
+ mAnimationState.mVariablePadding = a.getBoolean(
+ R.styleable.AnimationDrawable_variablePadding, mAnimationState.mVariablePadding);
+
+ mAnimationState.mOneShot = a.getBoolean(
+ R.styleable.AnimationDrawable_oneshot, mAnimationState.mOneShot);
}
@Override
@@ -357,7 +361,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
private final static class AnimationState extends DrawableContainerState {
private int[] mDurations;
- private boolean mOneShot;
+ private boolean mOneShot = false;
AnimationState(AnimationState orig, AnimationDrawable owner,
Resources res) {
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 669cef2..f80a5f4 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -16,6 +16,8 @@
package android.graphics.drawable;
+import com.android.internal.R;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -49,7 +51,7 @@ import java.io.IOException;
* @attr ref android.R.styleable#ClipDrawable_drawable
*/
public class ClipDrawable extends Drawable implements Drawable.Callback {
- private ClipState mClipState;
+ private ClipState mState;
private final Rect mTmpRect = new Rect();
public static final int HORIZONTAL = 1;
@@ -67,9 +69,9 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
public ClipDrawable(Drawable drawable, int gravity, int orientation) {
this(null, null);
- mClipState.mDrawable = drawable;
- mClipState.mGravity = gravity;
- mClipState.mOrientation = orientation;
+ mState.mDrawable = drawable;
+ mState.mGravity = gravity;
+ mState.mOrientation = orientation;
if (drawable != null) {
drawable.setCallback(this);
@@ -81,19 +83,22 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
throws XmlPullParserException, IOException {
super.inflate(r, parser, attrs, theme);
- int type;
-
- TypedArray a = obtainAttributes(
- r, theme, attrs, com.android.internal.R.styleable.ClipDrawable);
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ClipDrawable);
- int orientation = a.getInt(
- com.android.internal.R.styleable.ClipDrawable_clipOrientation,
- HORIZONTAL);
- int g = a.getInt(com.android.internal.R.styleable.ClipDrawable_gravity, Gravity.LEFT);
- Drawable dr = a.getDrawable(com.android.internal.R.styleable.ClipDrawable_drawable);
+ // Reset mDrawable to preserve old multiple-inflate behavior. This is
+ // silly, but we have CTS tests that rely on it.
+ mState.mDrawable = null;
+ updateStateFromTypedArray(a);
+ inflateChildElements(r, parser, attrs, theme);
+ verifyRequiredAttributes(a);
a.recycle();
+ }
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ Drawable dr = null;
+ int type;
final int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -103,35 +108,68 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
}
- if (dr == null) {
- throw new IllegalArgumentException("No drawable specified for <clip>");
+ if (dr != null) {
+ mState.mDrawable = dr;
+ dr.setCallback(this);
}
+ }
+
+ private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
+ // If we're not waiting on a theme, verify required attributes.
+ if (mState.mDrawable == null && (mState.mThemeAttrs == null
+ || mState.mThemeAttrs[R.styleable.ClipDrawable_drawable] == 0)) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + ": <clip> tag requires a 'drawable' attribute or "
+ + "child tag defining a drawable");
+ }
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) {
+ final ClipState state = mState;
+
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
- mClipState.mDrawable = dr;
- mClipState.mOrientation = orientation;
- mClipState.mGravity = g;
+ // Extract the theme attributes, if any.
+ state.mThemeAttrs = a.extractThemeAttrs();
- dr.setCallback(this);
+ state.mOrientation = a.getInt(R.styleable.ClipDrawable_clipOrientation, state.mOrientation);
+ state.mGravity = a.getInt(R.styleable.ClipDrawable_gravity, state.mGravity);
+
+ final Drawable dr = a.getDrawable(R.styleable.ClipDrawable_drawable);
+ if (dr != null) {
+ state.mDrawable = dr;
+ dr.setCallback(this);
+ }
}
@Override
public void applyTheme(Theme t) {
super.applyTheme(t);
- final ClipState state = mClipState;
+ final ClipState state = mState;
if (state == null) {
return;
}
- if (state.mDrawable != null) {
+ final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ClipDrawable);
+ 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() {
- final ClipState state = mClipState;
- return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme();
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
}
// overrides from Drawable.Callback
@@ -165,78 +203,78 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
- | mClipState.mChangingConfigurations
- | mClipState.mDrawable.getChangingConfigurations();
+ | mState.mChangingConfigurations
+ | mState.mDrawable.getChangingConfigurations();
}
@Override
public boolean getPadding(Rect padding) {
// XXX need to adjust padding!
- return mClipState.mDrawable.getPadding(padding);
+ return mState.mDrawable.getPadding(padding);
}
@Override
public boolean setVisible(boolean visible, boolean restart) {
- mClipState.mDrawable.setVisible(visible, restart);
+ mState.mDrawable.setVisible(visible, restart);
return super.setVisible(visible, restart);
}
@Override
public void setAlpha(int alpha) {
- mClipState.mDrawable.setAlpha(alpha);
+ mState.mDrawable.setAlpha(alpha);
}
@Override
public int getAlpha() {
- return mClipState.mDrawable.getAlpha();
+ return mState.mDrawable.getAlpha();
}
@Override
public void setColorFilter(ColorFilter cf) {
- mClipState.mDrawable.setColorFilter(cf);
+ mState.mDrawable.setColorFilter(cf);
}
@Override
public void setTintList(ColorStateList tint) {
- mClipState.mDrawable.setTintList(tint);
+ mState.mDrawable.setTintList(tint);
}
@Override
public void setTintMode(Mode tintMode) {
- mClipState.mDrawable.setTintMode(tintMode);
+ mState.mDrawable.setTintMode(tintMode);
}
@Override
public int getOpacity() {
- return mClipState.mDrawable.getOpacity();
+ return mState.mDrawable.getOpacity();
}
@Override
public boolean isStateful() {
- return mClipState.mDrawable.isStateful();
+ return mState.mDrawable.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
- return mClipState.mDrawable.setState(state);
+ return mState.mDrawable.setState(state);
}
@Override
protected boolean onLevelChange(int level) {
- mClipState.mDrawable.setLevel(level);
+ mState.mDrawable.setLevel(level);
invalidateSelf();
return true;
}
@Override
protected void onBoundsChange(Rect bounds) {
- mClipState.mDrawable.setBounds(bounds);
+ mState.mDrawable.setBounds(bounds);
}
@Override
public void draw(Canvas canvas) {
- if (mClipState.mDrawable.getLevel() == 0) {
+ if (mState.mDrawable.getLevel() == 0) {
return;
}
@@ -244,41 +282,41 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
final Rect bounds = getBounds();
int level = getLevel();
int w = bounds.width();
- final int iw = 0; //mClipState.mDrawable.getIntrinsicWidth();
- if ((mClipState.mOrientation & HORIZONTAL) != 0) {
+ final int iw = 0; //mState.mDrawable.getIntrinsicWidth();
+ if ((mState.mOrientation & HORIZONTAL) != 0) {
w -= (w - iw) * (10000 - level) / 10000;
}
int h = bounds.height();
- final int ih = 0; //mClipState.mDrawable.getIntrinsicHeight();
- if ((mClipState.mOrientation & VERTICAL) != 0) {
+ final int ih = 0; //mState.mDrawable.getIntrinsicHeight();
+ if ((mState.mOrientation & VERTICAL) != 0) {
h -= (h - ih) * (10000 - level) / 10000;
}
final int layoutDirection = getLayoutDirection();
- Gravity.apply(mClipState.mGravity, w, h, bounds, r, layoutDirection);
+ Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);
if (w > 0 && h > 0) {
canvas.save();
canvas.clipRect(r);
- mClipState.mDrawable.draw(canvas);
+ mState.mDrawable.draw(canvas);
canvas.restore();
}
}
@Override
public int getIntrinsicWidth() {
- return mClipState.mDrawable.getIntrinsicWidth();
+ return mState.mDrawable.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
- return mClipState.mDrawable.getIntrinsicHeight();
+ return mState.mDrawable.getIntrinsicHeight();
}
@Override
public ConstantState getConstantState() {
- if (mClipState.canConstantState()) {
- mClipState.mChangingConfigurations = getChangingConfigurations();
- return mClipState;
+ if (mState.canConstantState()) {
+ mState.mChangingConfigurations = getChangingConfigurations();
+ return mState;
}
return null;
}
@@ -286,14 +324,14 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
/** @hide */
@Override
public void setLayoutDirection(int layoutDirection) {
- mClipState.mDrawable.setLayoutDirection(layoutDirection);
+ mState.mDrawable.setLayoutDirection(layoutDirection);
super.setLayoutDirection(layoutDirection);
}
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
- mClipState.mDrawable.mutate();
+ mState.mDrawable.mutate();
mMutated = true;
}
return this;
@@ -304,21 +342,26 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
*/
public void clearMutated() {
super.clearMutated();
- mClipState.mDrawable.clearMutated();
+ mState.mDrawable.clearMutated();
mMutated = false;
}
final static class ClipState extends ConstantState {
- Drawable mDrawable;
+ int[] mThemeAttrs;
int mChangingConfigurations;
- int mOrientation;
- int mGravity;
+
+ Drawable mDrawable;
+
+ int mOrientation = HORIZONTAL;
+ int mGravity = Gravity.LEFT;
private boolean mCheckedConstantState;
private boolean mCanConstantState;
ClipState(ClipState orig, ClipDrawable owner, Resources res) {
if (orig != null) {
+ mThemeAttrs = orig.mThemeAttrs;
+ mChangingConfigurations = orig.mChangingConfigurations;
if (res != null) {
mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
@@ -335,6 +378,12 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
}
@Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
public Drawable newDrawable() {
return new ClipDrawable(this, null);
}
@@ -360,7 +409,7 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
}
private ClipDrawable(ClipState state, Resources res) {
- mClipState = new ClipState(state, this, res);
+ mState = new ClipState(state, this, res);
}
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index a903288..326490f 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -600,11 +600,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
Drawable[] mDrawables;
int mNumChildren;
- boolean mVariablePadding;
+ boolean mVariablePadding = false;
boolean mPaddingChecked;
Rect mConstantPadding;
- boolean mConstantSize;
+ boolean mConstantSize = false;
boolean mComputedConstantSize;
int mConstantWidth;
int mConstantHeight;
@@ -625,8 +625,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
boolean mMutated;
int mLayoutDirection;
- int mEnterFadeDuration;
- int mExitFadeDuration;
+ int mEnterFadeDuration = 0;
+ int mExitFadeDuration = 0;
boolean mAutoMirrored;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 47e0e46..1458238 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1089,7 +1089,7 @@ public class GradientDrawable extends Drawable {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mGradientState != null && mGradientState.canApplyTheme();
+ return (mGradientState != null && mGradientState.canApplyTheme()) || super.canApplyTheme();
}
private void applyThemeChildElements(Theme t) {
@@ -1632,7 +1632,7 @@ public class GradientDrawable extends Drawable {
public boolean canApplyTheme() {
return mThemeAttrs != null || mAttrSize != null || mAttrGradient != null
|| mAttrSolid != null || mAttrStroke != null || mAttrCorners != null
- || mAttrPadding != null;
+ || mAttrPadding != null || super.canApplyTheme();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index f1800e5..b88d9e6 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -55,7 +55,8 @@ import java.io.IOException;
public class InsetDrawable extends Drawable implements Drawable.Callback {
private final Rect mTmpRect = new Rect();
- private InsetState mInsetState;
+ private final InsetState mState;
+
private boolean mMutated;
/*package*/ InsetDrawable() {
@@ -70,11 +71,11 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
int insetRight, int insetBottom) {
this(null, null);
- mInsetState.mDrawable = drawable;
- mInsetState.mInsetLeft = insetLeft;
- mInsetState.mInsetTop = insetTop;
- mInsetState.mInsetRight = insetRight;
- mInsetState.mInsetBottom = insetBottom;
+ mState.mDrawable = drawable;
+ mState.mInsetLeft = insetLeft;
+ mState.mInsetTop = insetTop;
+ mState.mInsetRight = insetRight;
+ mState.mInsetBottom = insetBottom;
if (drawable != null) {
drawable.setCallback(this);
@@ -87,11 +88,20 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.InsetDrawable);
super.inflateWithAttributes(r, parser, a, R.styleable.InsetDrawable_visible);
- mInsetState.mDrawable = null;
+ // Reset mDrawable to preserve old multiple-inflate behavior. This is
+ // silly, but we have CTS tests that rely on it.
+ mState.mDrawable = null;
+
updateStateFromTypedArray(a);
+ inflateChildElements(r, parser, attrs, theme);
+ verifyRequiredAttributes(a);
+ a.recycle();
+ }
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
// Load inner XML elements.
- if (mInsetState.mDrawable == null) {
+ if (mState.mDrawable == null) {
int type;
while ((type=parser.next()) == XmlPullParser.TEXT) {
}
@@ -102,26 +112,23 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
+ "child tag defining a drawable");
}
final Drawable dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
- mInsetState.mDrawable = dr;
+ mState.mDrawable = dr;
dr.setCallback(this);
}
-
- verifyRequiredAttributes(a);
- a.recycle();
}
private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
// If we're not waiting on a theme, verify required attributes.
- if (mInsetState.mDrawable == null && (mInsetState.mThemeAttrs == null
- || mInsetState.mThemeAttrs[R.styleable.InsetDrawable_drawable] == 0)) {
- throw new XmlPullParserException(a.getPositionDescription() +
- ": <inset> tag requires a 'drawable' attribute or "
+ if (mState.mDrawable == null && (mState.mThemeAttrs == null
+ || mState.mThemeAttrs[R.styleable.InsetDrawable_drawable] == 0)) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + ": <inset> tag requires a 'drawable' attribute or "
+ "child tag defining a drawable");
}
}
private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
- final InsetState state = mInsetState;
+ final InsetState state = mState;
// Account for any configuration changes.
state.mChangingConfigurations |= a.getChangingConfigurations();
@@ -169,7 +176,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
public void applyTheme(Theme t) {
super.applyTheme(t);
- final InsetState state = mInsetState;
+ final InsetState state = mState;
if (state == null) {
return;
}
@@ -193,7 +200,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mInsetState != null && mInsetState.canApplyTheme();
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
}
@Override
@@ -222,112 +229,112 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
@Override
public void draw(Canvas canvas) {
- mInsetState.mDrawable.draw(canvas);
+ mState.mDrawable.draw(canvas);
}
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
- | mInsetState.mChangingConfigurations
- | mInsetState.mDrawable.getChangingConfigurations();
+ | mState.mChangingConfigurations
+ | mState.mDrawable.getChangingConfigurations();
}
@Override
public boolean getPadding(Rect padding) {
- boolean pad = mInsetState.mDrawable.getPadding(padding);
+ boolean pad = mState.mDrawable.getPadding(padding);
- padding.left += mInsetState.mInsetLeft;
- padding.right += mInsetState.mInsetRight;
- padding.top += mInsetState.mInsetTop;
- padding.bottom += mInsetState.mInsetBottom;
+ padding.left += mState.mInsetLeft;
+ padding.right += mState.mInsetRight;
+ padding.top += mState.mInsetTop;
+ padding.bottom += mState.mInsetBottom;
- return pad || (mInsetState.mInsetLeft | mInsetState.mInsetRight |
- mInsetState.mInsetTop | mInsetState.mInsetBottom) != 0;
+ return pad || (mState.mInsetLeft | mState.mInsetRight |
+ mState.mInsetTop | mState.mInsetBottom) != 0;
}
/** @hide */
@Override
public Insets getOpticalInsets() {
final Insets contentInsets = super.getOpticalInsets();
- return Insets.of(contentInsets.left + mInsetState.mInsetLeft,
- contentInsets.top + mInsetState.mInsetTop,
- contentInsets.right + mInsetState.mInsetRight,
- contentInsets.bottom + mInsetState.mInsetBottom);
+ return Insets.of(contentInsets.left + mState.mInsetLeft,
+ contentInsets.top + mState.mInsetTop,
+ contentInsets.right + mState.mInsetRight,
+ contentInsets.bottom + mState.mInsetBottom);
}
@Override
public void setHotspot(float x, float y) {
- mInsetState.mDrawable.setHotspot(x, y);
+ mState.mDrawable.setHotspot(x, y);
}
@Override
public void setHotspotBounds(int left, int top, int right, int bottom) {
- mInsetState.mDrawable.setHotspotBounds(left, top, right, bottom);
+ mState.mDrawable.setHotspotBounds(left, top, right, bottom);
}
/** @hide */
@Override
public void getHotspotBounds(Rect outRect) {
- mInsetState.mDrawable.getHotspotBounds(outRect);
+ mState.mDrawable.getHotspotBounds(outRect);
}
@Override
public boolean setVisible(boolean visible, boolean restart) {
- mInsetState.mDrawable.setVisible(visible, restart);
+ mState.mDrawable.setVisible(visible, restart);
return super.setVisible(visible, restart);
}
@Override
public void setAlpha(int alpha) {
- mInsetState.mDrawable.setAlpha(alpha);
+ mState.mDrawable.setAlpha(alpha);
}
@Override
public int getAlpha() {
- return mInsetState.mDrawable.getAlpha();
+ return mState.mDrawable.getAlpha();
}
@Override
public void setColorFilter(ColorFilter cf) {
- mInsetState.mDrawable.setColorFilter(cf);
+ mState.mDrawable.setColorFilter(cf);
}
@Override
public void setTintList(ColorStateList tint) {
- mInsetState.mDrawable.setTintList(tint);
+ mState.mDrawable.setTintList(tint);
}
@Override
public void setTintMode(Mode tintMode) {
- mInsetState.mDrawable.setTintMode(tintMode);
+ mState.mDrawable.setTintMode(tintMode);
}
/** {@hide} */
@Override
public void setLayoutDirection(int layoutDirection) {
- mInsetState.mDrawable.setLayoutDirection(layoutDirection);
+ mState.mDrawable.setLayoutDirection(layoutDirection);
}
@Override
public int getOpacity() {
- return mInsetState.mDrawable.getOpacity();
+ return mState.mDrawable.getOpacity();
}
@Override
public boolean isStateful() {
- return mInsetState.mDrawable.isStateful();
+ return mState.mDrawable.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
- boolean changed = mInsetState.mDrawable.setState(state);
+ boolean changed = mState.mDrawable.setState(state);
onBoundsChange(getBounds());
return changed;
}
@Override
protected boolean onLevelChange(int level) {
- return mInsetState.mDrawable.setLevel(level);
+ return mState.mDrawable.setLevel(level);
}
@Override
@@ -335,36 +342,36 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
final Rect r = mTmpRect;
r.set(bounds);
- r.left += mInsetState.mInsetLeft;
- r.top += mInsetState.mInsetTop;
- r.right -= mInsetState.mInsetRight;
- r.bottom -= mInsetState.mInsetBottom;
+ r.left += mState.mInsetLeft;
+ r.top += mState.mInsetTop;
+ r.right -= mState.mInsetRight;
+ r.bottom -= mState.mInsetBottom;
- mInsetState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
+ mState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
}
@Override
public int getIntrinsicWidth() {
- return mInsetState.mDrawable.getIntrinsicWidth()
- + mInsetState.mInsetLeft + mInsetState.mInsetRight;
+ return mState.mDrawable.getIntrinsicWidth()
+ + mState.mInsetLeft + mState.mInsetRight;
}
@Override
public int getIntrinsicHeight() {
- return mInsetState.mDrawable.getIntrinsicHeight()
- + mInsetState.mInsetTop + mInsetState.mInsetBottom;
+ return mState.mDrawable.getIntrinsicHeight()
+ + mState.mInsetTop + mState.mInsetBottom;
}
@Override
public void getOutline(@NonNull Outline outline) {
- mInsetState.mDrawable.getOutline(outline);
+ mState.mDrawable.getOutline(outline);
}
@Override
public ConstantState getConstantState() {
- if (mInsetState.canConstantState()) {
- mInsetState.mChangingConfigurations = getChangingConfigurations();
- return mInsetState;
+ if (mState.canConstantState()) {
+ mState.mChangingConfigurations = getChangingConfigurations();
+ return mState;
}
return null;
}
@@ -372,7 +379,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
- mInsetState.mDrawable.mutate();
+ mState.mDrawable.mutate();
mMutated = true;
}
return this;
@@ -383,7 +390,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
*/
public void clearMutated() {
super.clearMutated();
- mInsetState.mDrawable.clearMutated();
+ mState.mDrawable.clearMutated();
mMutated = false;
}
@@ -391,7 +398,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
* Returns the drawable wrapped by this InsetDrawable. May be null.
*/
public Drawable getDrawable() {
- return mInsetState.mDrawable;
+ return mState.mDrawable;
}
final static class InsetState extends ConstantState {
@@ -400,13 +407,13 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
Drawable mDrawable;
- int mInsetLeft;
- int mInsetTop;
- int mInsetRight;
- int mInsetBottom;
+ int mInsetLeft = 0;
+ int mInsetTop = 0;
+ int mInsetRight = 0;
+ int mInsetBottom = 0;
- boolean mCheckedConstantState;
- boolean mCanConstantState;
+ private boolean mCheckedConstantState;
+ private boolean mCanConstantState;
InsetState(InsetState orig, InsetDrawable owner, Resources res) {
if (orig != null) {
@@ -430,6 +437,12 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
@Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
public Drawable newDrawable() {
return new InsetDrawable(this, null);
}
@@ -444,12 +457,6 @@ 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;
@@ -461,7 +468,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
private InsetDrawable(InsetState state, Resources res) {
- mInsetState = new InsetState(state, this, res);
+ mState = new InsetState(state, this, res);
}
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 5107e10..689d225 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -275,7 +275,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mLayerState != null && mLayerState.canApplyTheme();
+ return (mLayerState != null && mLayerState.canApplyTheme()) || super.canApplyTheme();
}
/**
@@ -1020,7 +1020,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
@Override
public boolean canApplyTheme() {
- if (mThemeAttrs != null) {
+ if (mThemeAttrs != null || super.canApplyTheme()) {
return true;
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 316139b..e658279 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -473,7 +473,7 @@ public class RippleDrawable extends LayerDrawable {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mState != null && mState.canApplyTheme();
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 3f75bc3..9208a0a 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -31,7 +31,6 @@ import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
import android.util.TypedValue;
import android.util.AttributeSet;
-import android.util.Log;
import java.io.IOException;
@@ -314,6 +313,11 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
}
@Override
+ public boolean canApplyTheme() {
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
+ }
+
+ @Override
public void invalidateDrawable(Drawable who) {
final Callback callback = getCallback();
if (callback != null) {
@@ -401,100 +405,101 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
- final TypedArray a = obtainAttributes(r, theme, attrs,
- com.android.internal.R.styleable.RotateDrawable);
-
- super.inflateWithAttributes(r, parser, a,
- com.android.internal.R.styleable.RotateDrawable_visible);
-
- TypedValue tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotX);
- final boolean pivotXRel;
- final float pivotX;
- if (tv == null) {
- pivotXRel = true;
- pivotX = 0.5f;
- } else {
- pivotXRel = tv.type == TypedValue.TYPE_FRACTION;
- pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
- }
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.RotateDrawable);
+ super.inflateWithAttributes(r, parser, a, R.styleable.RotateDrawable_visible);
- tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotY);
- final boolean pivotYRel;
- final float pivotY;
- if (tv == null) {
- pivotYRel = true;
- pivotY = 0.5f;
- } else {
- pivotYRel = tv.type == TypedValue.TYPE_FRACTION;
- pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
- }
+ // Reset mDrawable to preserve old multiple-inflate behavior. This is
+ // silly, but we have CTS tests that rely on it.
+ mState.mDrawable = null;
+
+ updateStateFromTypedArray(a);
+ inflateChildElements(r, parser, attrs, theme);
+ verifyRequiredAttributes(a);
+ a.recycle();
+ }
- final float fromDegrees = a.getFloat(
- com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
- final float toDegrees = a.getFloat(
- com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);
+ @Override
+ public void applyTheme(Theme t) {
+ super.applyTheme(t);
- final int res = a.getResourceId(
- com.android.internal.R.styleable.RotateDrawable_drawable, 0);
- Drawable drawable = null;
- if (res > 0) {
- drawable = r.getDrawable(res, theme);
+ final RotateState state = mState;
+ if (state == null) {
+ return;
}
- a.recycle();
+ final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.RotateDrawable);
+ try {
+ updateStateFromTypedArray(a);
+ verifyRequiredAttributes(a);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ } finally {
+ a.recycle();
+ }
- final int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
- (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (state.mDrawable != null && state.mDrawable.canApplyTheme()) {
+ state.mDrawable.applyTheme(t);
+ }
+ }
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ Drawable dr = null;
+ int type;
+ final int outerDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type != XmlPullParser.START_TAG) {
continue;
}
-
- if ((drawable = Drawable.createFromXmlInner(r, parser, attrs, theme)) == null) {
- Log.w("drawable", "Bad element under <rotate>: "
- + parser .getName());
- }
+ dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
}
- if (drawable == null) {
- Log.w("drawable", "No drawable specified for <rotate>");
+ if (dr != null) {
+ mState.mDrawable = dr;
+ dr.setCallback(this);
}
+ }
- final RotateState st = mState;
- st.mDrawable = drawable;
- st.mPivotXRel = pivotXRel;
- st.mPivotX = pivotX;
- st.mPivotYRel = pivotYRel;
- st.mPivotY = pivotY;
- st.mFromDegrees = fromDegrees;
- st.mCurrentDegrees = fromDegrees;
- st.mToDegrees = toDegrees;
-
- if (drawable != null) {
- drawable.setCallback(this);
+ private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
+ // If we're not waiting on a theme, verify required attributes.
+ if (mState.mDrawable == null && (mState.mThemeAttrs == null
+ || mState.mThemeAttrs[R.styleable.ScaleDrawable_drawable] == 0)) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + ": <rotate> tag requires a 'drawable' attribute or "
+ + "child tag defining a drawable");
}
}
- @Override
- public void applyTheme(Theme t) {
- super.applyTheme(t);
-
+ private void updateStateFromTypedArray(TypedArray a) {
final RotateState state = mState;
- if (state == null) {
- return;
+
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
+
+ // Extract the theme attributes, if any.
+ state.mThemeAttrs = a.extractThemeAttrs();
+
+ if (a.hasValue(R.styleable.RotateDrawable_pivotX)) {
+ final TypedValue tv = a.peekValue(R.styleable.RotateDrawable_pivotX);
+ state.mPivotXRel = tv.type == TypedValue.TYPE_FRACTION;
+ state.mPivotX = state.mPivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
}
- if (state.mDrawable != null) {
- state.mDrawable.applyTheme(t);
+ if (a.hasValue(R.styleable.RotateDrawable_pivotY)) {
+ final TypedValue tv = a.peekValue(R.styleable.RotateDrawable_pivotY);
+ state.mPivotYRel = tv.type == TypedValue.TYPE_FRACTION;
+ state.mPivotY = state.mPivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
}
- }
- @Override
- public boolean canApplyTheme() {
- final RotateState state = mState;
- return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme();
+ state.mFromDegrees = a.getFloat(R.styleable.RotateDrawable_fromDegrees, state.mFromDegrees);
+ state.mToDegrees = a.getFloat(R.styleable.RotateDrawable_toDegrees, state.mToDegrees);
+
+ final Drawable dr = a.getDrawable(R.styleable.RotateDrawable_drawable);
+ if (dr != null) {
+ state.mDrawable = dr;
+ dr.setCallback(this);
+ }
}
@Override
@@ -521,25 +526,28 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
* rotations at the same time.
*/
final static class RotateState extends Drawable.ConstantState {
- Drawable mDrawable;
-
+ int[] mThemeAttrs;
int mChangingConfigurations;
- boolean mPivotXRel;
- float mPivotX;
- boolean mPivotYRel;
- float mPivotY;
+ Drawable mDrawable;
- float mFromDegrees;
- float mToDegrees;
+ boolean mPivotXRel = true;
+ float mPivotX = 0.5f;
+ boolean mPivotYRel = true;
+ float mPivotY = 0.5f;
- float mCurrentDegrees;
+ float mFromDegrees = 0.0f;
+ float mToDegrees = 360.0f;
+
+ float mCurrentDegrees = 0.0f;
- private boolean mCanConstantState;
private boolean mCheckedConstantState;
+ private boolean mCanConstantState;
- public RotateState(RotateState orig, RotateDrawable owner, Resources res) {
+ RotateState(RotateState orig, RotateDrawable owner, Resources res) {
if (orig != null) {
+ mThemeAttrs = orig.mThemeAttrs;
+ mChangingConfigurations = orig.mChangingConfigurations;
if (res != null) {
mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
@@ -553,13 +561,20 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
mPivotX = orig.mPivotX;
mPivotYRel = orig.mPivotYRel;
mPivotY = orig.mPivotY;
- mFromDegrees = mCurrentDegrees = orig.mFromDegrees;
+ mFromDegrees = orig.mFromDegrees;
mToDegrees = orig.mToDegrees;
- mCanConstantState = mCheckedConstantState = true;
+ mCurrentDegrees = orig.mCurrentDegrees;
+ mCheckedConstantState = mCanConstantState = true;
}
}
@Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
public Drawable newDrawable() {
return new RotateDrawable(this, null);
}
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 9a5b8fb..fbe38b4 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -16,6 +16,8 @@
package android.graphics.drawable;
+import com.android.internal.R;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -47,7 +49,7 @@ import java.io.IOException;
* @attr ref android.R.styleable#ScaleDrawable_drawable
*/
public class ScaleDrawable extends Drawable implements Drawable.Callback {
- private ScaleState mScaleState;
+ private ScaleState mState;
private boolean mMutated;
private final Rect mTmpRect = new Rect();
@@ -58,10 +60,10 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
public ScaleDrawable(Drawable drawable, int gravity, float scaleWidth, float scaleHeight) {
this(null, null);
- mScaleState.mDrawable = drawable;
- mScaleState.mGravity = gravity;
- mScaleState.mScaleWidth = scaleWidth;
- mScaleState.mScaleHeight = scaleHeight;
+ mState.mDrawable = drawable;
+ mState.mGravity = gravity;
+ mState.mScaleWidth = scaleWidth;
+ mState.mScaleHeight = scaleHeight;
if (drawable != null) {
drawable.setCallback(this);
@@ -72,18 +74,18 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
* Returns the drawable scaled by this ScaleDrawable.
*/
public Drawable getDrawable() {
- return mScaleState.mDrawable;
+ return mState.mDrawable;
}
- private static float getPercent(TypedArray a, int name) {
- String s = a.getString(name);
+ private static float getPercent(TypedArray a, int name, float defaultValue) {
+ final String s = a.getString(name);
if (s != null) {
if (s.endsWith("%")) {
String f = s.substring(0, s.length() - 1);
return Float.parseFloat(f) / 100.0f;
}
}
- return -1;
+ return defaultValue;
}
@Override
@@ -91,20 +93,48 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
throws XmlPullParserException, IOException {
super.inflate(r, parser, attrs, theme);
- int type;
-
- TypedArray a = obtainAttributes(
- r, theme, attrs, com.android.internal.R.styleable.ScaleDrawable);
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ScaleDrawable);
- float sw = getPercent(a, com.android.internal.R.styleable.ScaleDrawable_scaleWidth);
- float sh = getPercent(a, com.android.internal.R.styleable.ScaleDrawable_scaleHeight);
- int g = a.getInt(com.android.internal.R.styleable.ScaleDrawable_scaleGravity, Gravity.LEFT);
- boolean min = a.getBoolean(
- com.android.internal.R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, false);
- Drawable dr = a.getDrawable(com.android.internal.R.styleable.ScaleDrawable_drawable);
+ // Reset mDrawable to preserve old multiple-inflate behavior. This is
+ // silly, but we have CTS tests that rely on it.
+ mState.mDrawable = null;
+ updateStateFromTypedArray(a);
+ inflateChildElements(r, parser, attrs, theme);
+ verifyRequiredAttributes(a);
a.recycle();
+ }
+
+ @Override
+ public void applyTheme(Theme t) {
+ super.applyTheme(t);
+
+ final ScaleState state = mState;
+ if (state == null) {
+ return;
+ }
+
+ if (state.mThemeAttrs == null) {
+ final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ScaleDrawable);
+ 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);
+ }
+ }
+
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ Drawable dr = null;
+ int type;
final int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -114,38 +144,49 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
}
- if (dr == null) {
- throw new IllegalArgumentException("No drawable specified for <scale>");
- }
-
- mScaleState.mDrawable = dr;
- mScaleState.mScaleWidth = sw;
- mScaleState.mScaleHeight = sh;
- mScaleState.mGravity = g;
- mScaleState.mUseIntrinsicSizeAsMin = min;
if (dr != null) {
+ mState.mDrawable = dr;
dr.setCallback(this);
}
}
- @Override
- public void applyTheme(Theme t) {
- super.applyTheme(t);
-
- final ScaleState state = mScaleState;
- if (state == null) {
- return;
+ private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
+ // If we're not waiting on a theme, verify required attributes.
+ if (mState.mDrawable == null && (mState.mThemeAttrs == null
+ || mState.mThemeAttrs[R.styleable.ScaleDrawable_drawable] == 0)) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + ": <scale> tag requires a 'drawable' attribute or "
+ + "child tag defining a drawable");
}
+ }
- if (state.mDrawable != null) {
- state.mDrawable.applyTheme(t);
+ private void updateStateFromTypedArray(TypedArray a) {
+ final ScaleState state = mState;
+
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
+
+ // Extract the theme attributes, if any.
+ state.mThemeAttrs = a.extractThemeAttrs();
+
+ state.mScaleWidth = getPercent(
+ a, R.styleable.ScaleDrawable_scaleWidth, state.mScaleWidth);
+ state.mScaleHeight = getPercent(
+ a, R.styleable.ScaleDrawable_scaleHeight, state.mScaleHeight);
+ state.mGravity = a.getInt(R.styleable.ScaleDrawable_scaleGravity, Gravity.LEFT);
+ state.mUseIntrinsicSizeAsMin = a.getBoolean(
+ R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, false);
+
+ final Drawable dr = a.getDrawable(R.styleable.ScaleDrawable_drawable);
+ if (dr != null) {
+ state.mDrawable = dr;
+ dr.setCallback(this);
}
}
@Override
public boolean canApplyTheme() {
- final ScaleState state = mScaleState;
- return state != null && state.mDrawable != null && state.mDrawable.canApplyTheme();
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
}
// overrides from Drawable.Callback
@@ -172,74 +213,74 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
@Override
public void draw(Canvas canvas) {
- if (mScaleState.mDrawable.getLevel() != 0)
- mScaleState.mDrawable.draw(canvas);
+ if (mState.mDrawable.getLevel() != 0)
+ mState.mDrawable.draw(canvas);
}
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
- | mScaleState.mChangingConfigurations
- | mScaleState.mDrawable.getChangingConfigurations();
+ | mState.mChangingConfigurations
+ | mState.mDrawable.getChangingConfigurations();
}
@Override
public boolean getPadding(Rect padding) {
// XXX need to adjust padding!
- return mScaleState.mDrawable.getPadding(padding);
+ return mState.mDrawable.getPadding(padding);
}
@Override
public boolean setVisible(boolean visible, boolean restart) {
- mScaleState.mDrawable.setVisible(visible, restart);
+ mState.mDrawable.setVisible(visible, restart);
return super.setVisible(visible, restart);
}
@Override
public void setAlpha(int alpha) {
- mScaleState.mDrawable.setAlpha(alpha);
+ mState.mDrawable.setAlpha(alpha);
}
@Override
public int getAlpha() {
- return mScaleState.mDrawable.getAlpha();
+ return mState.mDrawable.getAlpha();
}
@Override
public void setColorFilter(ColorFilter cf) {
- mScaleState.mDrawable.setColorFilter(cf);
+ mState.mDrawable.setColorFilter(cf);
}
@Override
public void setTintList(ColorStateList tint) {
- mScaleState.mDrawable.setTintList(tint);
+ mState.mDrawable.setTintList(tint);
}
@Override
public void setTintMode(Mode tintMode) {
- mScaleState.mDrawable.setTintMode(tintMode);
+ mState.mDrawable.setTintMode(tintMode);
}
@Override
public int getOpacity() {
- return mScaleState.mDrawable.getOpacity();
+ return mState.mDrawable.getOpacity();
}
@Override
public boolean isStateful() {
- return mScaleState.mDrawable.isStateful();
+ return mState.mDrawable.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
- boolean changed = mScaleState.mDrawable.setState(state);
+ boolean changed = mState.mDrawable.setState(state);
onBoundsChange(getBounds());
return changed;
}
@Override
protected boolean onLevelChange(int level) {
- mScaleState.mDrawable.setLevel(level);
+ mState.mDrawable.setLevel(level);
onBoundsChange(getBounds());
invalidateSelf();
return true;
@@ -248,41 +289,41 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
@Override
protected void onBoundsChange(Rect bounds) {
final Rect r = mTmpRect;
- final boolean min = mScaleState.mUseIntrinsicSizeAsMin;
+ final boolean min = mState.mUseIntrinsicSizeAsMin;
int level = getLevel();
int w = bounds.width();
- if (mScaleState.mScaleWidth > 0) {
- final int iw = min ? mScaleState.mDrawable.getIntrinsicWidth() : 0;
- w -= (int) ((w - iw) * (10000 - level) * mScaleState.mScaleWidth / 10000);
+ if (mState.mScaleWidth > 0) {
+ final int iw = min ? mState.mDrawable.getIntrinsicWidth() : 0;
+ w -= (int) ((w - iw) * (10000 - level) * mState.mScaleWidth / 10000);
}
int h = bounds.height();
- if (mScaleState.mScaleHeight > 0) {
- final int ih = min ? mScaleState.mDrawable.getIntrinsicHeight() : 0;
- h -= (int) ((h - ih) * (10000 - level) * mScaleState.mScaleHeight / 10000);
+ if (mState.mScaleHeight > 0) {
+ final int ih = min ? mState.mDrawable.getIntrinsicHeight() : 0;
+ h -= (int) ((h - ih) * (10000 - level) * mState.mScaleHeight / 10000);
}
final int layoutDirection = getLayoutDirection();
- Gravity.apply(mScaleState.mGravity, w, h, bounds, r, layoutDirection);
+ Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);
if (w > 0 && h > 0) {
- mScaleState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
+ mState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
}
}
@Override
public int getIntrinsicWidth() {
- return mScaleState.mDrawable.getIntrinsicWidth();
+ return mState.mDrawable.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
- return mScaleState.mDrawable.getIntrinsicHeight();
+ return mState.mDrawable.getIntrinsicHeight();
}
@Override
public ConstantState getConstantState() {
- if (mScaleState.canConstantState()) {
- mScaleState.mChangingConfigurations = getChangingConfigurations();
- return mScaleState;
+ if (mState.canConstantState()) {
+ mState.mChangingConfigurations = getChangingConfigurations();
+ return mState;
}
return null;
}
@@ -290,7 +331,7 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
- mScaleState.mDrawable.mutate();
+ mState.mDrawable.mutate();
mMutated = true;
}
return this;
@@ -301,23 +342,28 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
*/
public void clearMutated() {
super.clearMutated();
- mScaleState.mDrawable.clearMutated();
+ mState.mDrawable.clearMutated();
mMutated = false;
}
final static class ScaleState extends ConstantState {
- Drawable mDrawable;
+ int[] mThemeAttrs;
int mChangingConfigurations;
- float mScaleWidth;
- float mScaleHeight;
- int mGravity;
- boolean mUseIntrinsicSizeAsMin;
+
+ Drawable mDrawable;
+
+ float mScaleWidth = 1.0f;
+ float mScaleHeight = 1.0f;
+ int mGravity = Gravity.LEFT;
+ boolean mUseIntrinsicSizeAsMin = false;
private boolean mCheckedConstantState;
private boolean mCanConstantState;
ScaleState(ScaleState orig, ScaleDrawable owner, Resources res) {
if (orig != null) {
+ mThemeAttrs = orig.mThemeAttrs;
+ mChangingConfigurations = orig.mChangingConfigurations;
if (res != null) {
mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
@@ -336,6 +382,12 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
}
@Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
public Drawable newDrawable() {
return new ScaleDrawable(this, null);
}
@@ -361,7 +413,7 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
}
private ScaleDrawable(ScaleState state, Resources res) {
- mScaleState = new ScaleState(state, this, res);
+ mState = new ScaleState(state, this, res);
}
}
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index a299b3c..963943b 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -117,26 +117,48 @@ public class StateListDrawable extends DrawableContainer {
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
-
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.StateListDrawable);
+ super.inflateWithAttributes(r, parser, a, R.styleable.StateListDrawable_visible);
+ updateStateFromTypedArray(a);
+ a.recycle();
- super.inflateWithAttributes(r, parser, a,
- R.styleable.StateListDrawable_visible);
-
- mStateListState.setVariablePadding(a.getBoolean(
- R.styleable.StateListDrawable_variablePadding, false));
- mStateListState.setConstantSize(a.getBoolean(
- R.styleable.StateListDrawable_constantSize, false));
- mStateListState.setEnterFadeDuration(a.getInt(
- R.styleable.StateListDrawable_enterFadeDuration, 0));
- mStateListState.setExitFadeDuration(a.getInt(
- R.styleable.StateListDrawable_exitFadeDuration, 0));
+ inflateChildElements(r, parser, attrs, theme);
- setDither(a.getBoolean(R.styleable.StateListDrawable_dither, DEFAULT_DITHER));
- setAutoMirrored(a.getBoolean(R.styleable.StateListDrawable_autoMirrored, false));
+ onStateChange(getState());
+ }
- a.recycle();
+ /**
+ * Updates the constant state from the values in the typed array.
+ */
+ private void updateStateFromTypedArray(TypedArray a) {
+ final StateListState state = mStateListState;
+
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
+
+ // Extract the theme attributes, if any.
+ state.mThemeAttrs = a.extractThemeAttrs();
+
+ state.mVariablePadding = a.getBoolean(
+ R.styleable.StateListDrawable_variablePadding, state.mVariablePadding);
+ state.mConstantSize = a.getBoolean(
+ R.styleable.StateListDrawable_constantSize, state.mConstantSize);
+ state.mEnterFadeDuration = a.getInt(
+ R.styleable.StateListDrawable_enterFadeDuration, state.mEnterFadeDuration);
+ state.mExitFadeDuration = a.getInt(
+ R.styleable.StateListDrawable_exitFadeDuration, state.mExitFadeDuration);
+ state.mDither = a.getBoolean(
+ R.styleable.StateListDrawable_dither, state.mDither);
+ state.mAutoMirrored = a.getBoolean(
+ R.styleable.StateListDrawable_autoMirrored, state.mAutoMirrored);
+ }
+ /**
+ * Inflates child elements from XML.
+ */
+ private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ final StateListState state = mStateListState;
final int innerDepth = parser.getDepth() + 1;
int type;
int depth;
@@ -185,10 +207,8 @@ public class StateListDrawable extends DrawableContainer {
dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
}
- mStateListState.addStateSet(states, dr);
+ state.addStateSet(states, dr);
}
-
- onStateChange(getState());
}
StateListState getStateListState() {
@@ -282,6 +302,7 @@ public class StateListDrawable extends DrawableContainer {
}
static class StateListState extends DrawableContainerState {
+ int[] mThemeAttrs;
int[][] mStateSets;
StateListState(StateListState orig, StateListDrawable owner, Resources res) {
@@ -298,7 +319,11 @@ public class StateListDrawable extends DrawableContainer {
mStateSets[i] = set.clone();
}
}
+
+ mThemeAttrs = orig.mThemeAttrs;
+ mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length);
} else {
+ mThemeAttrs = null;
mStateSets = new int[getCapacity()][];
}
}
@@ -331,6 +356,11 @@ public class StateListDrawable extends DrawableContainer {
}
@Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null || super.canApplyTheme();
+ }
+
+ @Override
public void growArray(int oldSize, int newSize) {
super.growArray(oldSize, newSize);
final int[][] newStateSets = new int[newSize][];
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 848fc53..8b0f635 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -361,7 +361,7 @@ public class VectorDrawable extends Drawable {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme();
+ return (mVectorState != null && mVectorState.canApplyTheme()) || super.canApplyTheme();
}
@Override
@@ -750,8 +750,8 @@ public class VectorDrawable extends Drawable {
@Override
public boolean canApplyTheme() {
- return super.canApplyTheme() || mThemeAttrs != null
- || (mVPathRenderer != null && mVPathRenderer.canApplyTheme());
+ return mThemeAttrs != null || (mVPathRenderer != null && mVPathRenderer.canApplyTheme())
+ || super.canApplyTheme();
}
public VectorDrawableState() {