summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2015-02-23 20:38:58 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-02-23 20:39:01 +0000
commitb3f3762ee0f57c94ea25bc1cc9d4baf0ee2a2976 (patch)
tree91d4c19db8c884df6d55a2b2c31e87c84bda3708 /graphics
parentdb871da48fe65b33bfaf5fb6c0bf328b291a667e (diff)
parenta12962207155305da44b5a1b8fb9acaed358c14c (diff)
downloadframeworks_base-b3f3762ee0f57c94ea25bc1cc9d4baf0ee2a2976.zip
frameworks_base-b3f3762ee0f57c94ea25bc1cc9d4baf0ee2a2976.tar.gz
frameworks_base-b3f3762ee0f57c94ea25bc1cc9d4baf0ee2a2976.tar.bz2
Merge "Unify wrapper-type drawables"
Diffstat (limited to 'graphics')
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java311
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java11
-rw-r--r--graphics/java/android/graphics/drawable/ClipDrawable.java316
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java52
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java19
-rw-r--r--graphics/java/android/graphics/drawable/DrawableWrapper.java443
-rw-r--r--graphics/java/android/graphics/drawable/InsetDrawable.java300
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java9
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/RotateDrawable.java448
-rw-r--r--graphics/java/android/graphics/drawable/ScaleDrawable.java376
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java10
12 files changed, 866 insertions, 1430 deletions
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index d2799e1..db94d89 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -20,15 +20,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Canvas;
import android.graphics.Rect;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuff.Mode;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
import android.util.AttributeSet;
import android.util.TypedValue;
-import android.util.Log;
import android.os.SystemClock;
import org.xmlpull.v1.XmlPullParser;
@@ -41,35 +37,15 @@ import com.android.internal.R;
/**
* @hide
*/
-public class AnimatedRotateDrawable extends Drawable implements Drawable.Callback, Runnable,
- Animatable {
- private static final String TAG = "AnimatedRotateDrawable";
-
+public class AnimatedRotateDrawable extends DrawableWrapper implements Runnable, Animatable {
private AnimatedRotateState mState;
- private boolean mMutated;
+
private float mCurrentDegrees;
private float mIncrement;
private boolean mRunning;
public AnimatedRotateDrawable() {
- this(null, null);
- }
-
- private AnimatedRotateDrawable(AnimatedRotateState rotateState, Resources res) {
- mState = new AnimatedRotateState(rotateState, this, res);
- init();
- }
-
- private void init() {
- final AnimatedRotateState state = mState;
- mIncrement = 360.0f / state.mFramesCount;
- final Drawable drawable = state.mDrawable;
- if (drawable != null) {
- drawable.setFilterBitmap(true);
- if (drawable instanceof BitmapDrawable) {
- ((BitmapDrawable) drawable).setAntiAlias(true);
- }
- }
+ this(new AnimatedRotateState(null), null);
}
@Override
@@ -131,8 +107,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
@Override
public boolean setVisible(boolean visible, boolean restart) {
- mState.mDrawable.setVisible(visible, restart);
- boolean changed = super.setVisible(visible, restart);
+ final boolean changed = super.setVisible(visible, restart);
if (visible) {
if (changed || restart) {
mCurrentDegrees = 0.0f;
@@ -144,123 +119,6 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
return changed;
}
- /**
- * Returns the drawable rotated by this RotateDrawable.
- */
- public Drawable getDrawable() {
- return mState.mDrawable;
- }
-
- @Override
- public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mState.mChangingConfigurations
- | mState.mDrawable.getChangingConfigurations();
- }
-
- @Override
- public void setAlpha(int alpha) {
- mState.mDrawable.setAlpha(alpha);
- }
-
- @Override
- public int getAlpha() {
- return mState.mDrawable.getAlpha();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- mState.mDrawable.setColorFilter(cf);
- }
-
- @Override
- public void setTintList(ColorStateList tint) {
- mState.mDrawable.setTintList(tint);
- }
-
- @Override
- public void setTintMode(Mode tintMode) {
- mState.mDrawable.setTintMode(tintMode);
- }
-
- @Override
- public int getOpacity() {
- return mState.mDrawable.getOpacity();
- }
-
- @Override
- public boolean canApplyTheme() {
- return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
- }
-
- @Override
- public void invalidateDrawable(Drawable who) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.invalidateDrawable(this);
- }
- }
-
- @Override
- public void scheduleDrawable(Drawable who, Runnable what, long when) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.scheduleDrawable(this, what, when);
- }
- }
-
- @Override
- public void unscheduleDrawable(Drawable who, Runnable what) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.unscheduleDrawable(this, what);
- }
- }
-
- @Override
- public boolean getPadding(Rect padding) {
- return mState.mDrawable.getPadding(padding);
- }
-
- @Override
- public boolean isStateful() {
- return mState.mDrawable.isStateful();
- }
-
- @Override
- protected void onBoundsChange(Rect bounds) {
- mState.mDrawable.setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
- }
-
- @Override
- protected boolean onLevelChange(int level) {
- return mState.mDrawable.setLevel(level);
- }
-
- @Override
- protected boolean onStateChange(int[] state) {
- return mState.mDrawable.setState(state);
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mState.mDrawable.getIntrinsicWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mState.mDrawable.getIntrinsicHeight();
- }
-
- @Override
- public ConstantState getConstantState() {
- if (mState.canConstantState()) {
- mState.mChangingConfigurations = getChangingConfigurations();
- return mState;
- }
- return null;
- }
-
@Override
public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
@NonNull AttributeSet attrs, @Nullable Theme theme)
@@ -268,50 +126,27 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.AnimatedRotateDrawable);
super.inflateWithAttributes(r, parser, a, R.styleable.AnimatedRotateDrawable_visible);
updateStateFromTypedArray(a);
+ verifyRequiredAttributes(a);
a.recycle();
- inflateChildElements(r, parser, attrs, theme);
-
- init();
+ updateLocalState();
}
- @Override
- public void applyTheme(@Nullable Theme t) {
- super.applyTheme(t);
-
- final AnimatedRotateState state = mState;
- if (state == null) {
- return;
- }
-
- 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 (state.mDrawable != null && state.mDrawable.canApplyTheme()) {
- state.mDrawable.applyTheme(t);
+ private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
+ // If we're not waiting on a theme, verify required attributes.
+ if (getDrawable() == 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");
}
-
- init();
}
- private void updateStateFromTypedArray(TypedArray a) {
- final AnimatedRotateState state = mState;
-
- // Account for any configuration changes.
- state.mChangingConfigurations |= a.getChangingConfigurations();
+ @Override
+ void updateStateFromTypedArray(TypedArray a) {
+ super.updateStateFromTypedArray(a);
- // Extract the theme attributes, if any.
- state.mThemeAttrs = a.extractThemeAttrs();
+ final AnimatedRotateState state = mState;
if (a.hasValue(R.styleable.AnimatedRotateDrawable_pivotX)) {
final TypedValue tv = a.peekValue(R.styleable.AnimatedRotateDrawable_pivotX);
@@ -332,43 +167,35 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
final Drawable dr = a.getDrawable(R.styleable.AnimatedRotateDrawable_drawable);
if (dr != null) {
- state.mDrawable = dr;
- dr.setCallback(this);
+ setDrawable(dr);
}
}
- private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
- Theme theme) throws XmlPullParserException, IOException {
+ @Override
+ public void applyTheme(@Nullable Theme t) {
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.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 (dr != null) {
- state.mDrawable = dr;
- dr.setCallback(this);
- }
- }
+ // The drawable may have changed as a result of applying the theme, so
+ // apply the theme to the wrapped drawable last.
+ super.applyTheme(t);
- 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");
- }
+ updateLocalState();
}
public void setFramesCount(int framesCount) {
@@ -380,25 +207,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
mState.mFrameDuration = framesDuration;
}
- @Override
- public Drawable mutate() {
- if (!mMutated && super.mutate() == this) {
- mState.mDrawable.mutate();
- mMutated = true;
- }
- return this;
- }
-
- /**
- * @hide
- */
- public void clearMutated() {
- super.clearMutated();
- mState.mDrawable.clearMutated();
- mMutated = false;
- }
-
- final static class AnimatedRotateState extends Drawable.ConstantState {
+ static final class AnimatedRotateState extends DrawableWrapper.DrawableWrapperState {
Drawable mDrawable;
int[] mThemeAttrs;
@@ -414,35 +223,20 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
private boolean mCanConstantState;
private boolean mCheckedConstantState;
- public AnimatedRotateState(AnimatedRotateState orig, AnimatedRotateDrawable owner,
- Resources res) {
+ public AnimatedRotateState(AnimatedRotateState orig) {
+ super(orig);
+
if (orig != null) {
- if (res != null) {
- mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
- } else {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
- }
- mDrawable.setCallback(owner);
- 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;
mPivotY = orig.mPivotY;
mFramesCount = orig.mFramesCount;
mFrameDuration = orig.mFrameDuration;
- mCanConstantState = mCheckedConstantState = true;
}
}
@Override
- public Drawable newDrawable() {
- return new AnimatedRotateDrawable(this, null);
- }
-
- @Override
public Drawable newDrawable(Resources res) {
return new AnimatedRotateDrawable(this, res);
}
@@ -467,4 +261,27 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac
return mCanConstantState;
}
}
+
+ private AnimatedRotateDrawable(AnimatedRotateState state, Resources res) {
+ super(state, res);
+
+ mState = state;
+
+ updateLocalState();
+ }
+
+ private void updateLocalState() {
+ final AnimatedRotateState state = mState;
+ mIncrement = 360.0f / state.mFramesCount;
+
+ // Force the wrapped drawable to use filtering and AA, if applicable,
+ // so that it looks smooth when rotated.
+ final Drawable drawable = state.mDrawable;
+ if (drawable != null) {
+ drawable.setFilterBitmap(true);
+ if (drawable instanceof BitmapDrawable) {
+ ((BitmapDrawable) drawable).setAntiAlias(true);
+ }
+ }
+ }
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 2a17a60..17e5b0b 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -197,6 +197,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
}
@Override
+ public boolean onLayoutDirectionChange(int layoutDirection) {
+ return mAnimatedVectorState.mVectorDrawable.setLayoutDirection(layoutDirection);
+ }
+
+ @Override
public int getAlpha() {
return mAnimatedVectorState.mVectorDrawable.getAlpha();
}
@@ -237,12 +242,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
return super.setVisible(visible, restart);
}
- /** {@hide} */
- @Override
- public void setLayoutDirection(int layoutDirection) {
- mAnimatedVectorState.mVectorDrawable.setLayoutDirection(layoutDirection);
- }
-
@Override
public boolean isStateful() {
return mAnimatedVectorState.mVectorDrawable.isStateful();
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index e5b2b76..f3574e8 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -50,32 +50,36 @@ import java.io.IOException;
* @attr ref android.R.styleable#ClipDrawable_gravity
* @attr ref android.R.styleable#ClipDrawable_drawable
*/
-public class ClipDrawable extends Drawable implements Drawable.Callback {
- private ClipState mState;
- private final Rect mTmpRect = new Rect();
-
+public class ClipDrawable extends DrawableWrapper {
public static final int HORIZONTAL = 1;
public static final int VERTICAL = 2;
- private boolean mMutated;
+ private static final int MAX_LEVEL = 10000;
+
+ private final Rect mTmpRect = new Rect();
+
+ private ClipState mState;
ClipDrawable() {
- this(null, null);
+ this(new ClipState(null), null);
}
/**
- * @param orientation Bitwise-or of {@link #HORIZONTAL} and/or {@link #VERTICAL}
+ * Creates a new clip drawable with the specified gravity and orientation.
+ *
+ * @param drawable the drawable to clip
+ * @param gravity gravity constant (see {@link Gravity} used to position
+ * the clipped drawable within the parent container
+ * @param orientation bitwise-or of {@link #HORIZONTAL} and/or
+ * {@link #VERTICAL}
*/
public ClipDrawable(Drawable drawable, int gravity, int orientation) {
- this(null, null);
+ this(new ClipState(null), null);
- mState.mDrawable = drawable;
mState.mGravity = gravity;
mState.mOrientation = orientation;
- if (drawable != null) {
- drawable.setCallback(this);
- }
+ setDrawable(drawable);
}
@Override
@@ -84,39 +88,15 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
super.inflate(r, parser, attrs, theme);
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ClipDrawable);
-
- // 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);
+ inflateChildDrawable(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)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
- }
-
- 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
+ if (getDrawable() == null && (mState.mThemeAttrs == null
|| mState.mThemeAttrs[R.styleable.ClipDrawable_drawable] == 0)) {
throw new XmlPullParserException(a.getPositionDescription()
+ ": <clip> tag requires a 'drawable' attribute or "
@@ -124,292 +104,110 @@ public class ClipDrawable extends Drawable implements Drawable.Callback {
}
}
- private void updateStateFromTypedArray(TypedArray a) {
- final ClipState state = mState;
-
- // Account for any configuration changes.
- state.mChangingConfigurations |= a.getChangingConfigurations();
-
- // Extract the theme attributes, if any.
- state.mThemeAttrs = a.extractThemeAttrs();
+ @Override
+ void updateStateFromTypedArray(TypedArray a) {
+ super.updateStateFromTypedArray(a);
- state.mOrientation = a.getInt(R.styleable.ClipDrawable_clipOrientation, state.mOrientation);
- state.mGravity = a.getInt(R.styleable.ClipDrawable_gravity, state.mGravity);
+ final ClipState state = mState;
+ 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);
+ setDrawable(dr);
}
}
@Override
public void applyTheme(Theme t) {
- super.applyTheme(t);
-
final ClipState state = mState;
- if (state == null || state.mThemeAttrs == null) {
+ if (state == null) {
return;
}
- 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() {
- return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
- }
-
- // overrides from Drawable.Callback
-
- @Override
- public void invalidateDrawable(Drawable who) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.invalidateDrawable(this);
- }
- }
-
- @Override
- public void scheduleDrawable(Drawable who, Runnable what, long when) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.scheduleDrawable(this, what, when);
- }
- }
-
- @Override
- public void unscheduleDrawable(Drawable who, Runnable what) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.unscheduleDrawable(this, what);
+ if (state.mThemeAttrs != 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();
+ }
}
- }
-
- // overrides from Drawable
-
- @Override
- public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mState.mChangingConfigurations
- | mState.mDrawable.getChangingConfigurations();
- }
-
- @Override
- public boolean getPadding(Rect padding) {
- // XXX need to adjust padding!
- return mState.mDrawable.getPadding(padding);
- }
-
- @Override
- public boolean setVisible(boolean visible, boolean restart) {
- mState.mDrawable.setVisible(visible, restart);
- return super.setVisible(visible, restart);
- }
- @Override
- public void setAlpha(int alpha) {
- mState.mDrawable.setAlpha(alpha);
- }
-
- @Override
- public int getAlpha() {
- return mState.mDrawable.getAlpha();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- mState.mDrawable.setColorFilter(cf);
- }
-
- @Override
- public void setTintList(ColorStateList tint) {
- mState.mDrawable.setTintList(tint);
- }
-
- @Override
- public void setTintMode(Mode tintMode) {
- mState.mDrawable.setTintMode(tintMode);
- }
-
- @Override
- public int getOpacity() {
- return mState.mDrawable.getOpacity();
- }
-
- @Override
- public boolean isStateful() {
- return mState.mDrawable.isStateful();
- }
-
- @Override
- protected boolean onStateChange(int[] state) {
- return mState.mDrawable.setState(state);
+ // The drawable may have changed as a result of applying the theme, so
+ // apply the theme to the wrapped drawable last.
+ super.applyTheme(t);
}
@Override
protected boolean onLevelChange(int level) {
- mState.mDrawable.setLevel(level);
+ super.onLevelChange(level);
invalidateSelf();
return true;
}
@Override
- protected void onBoundsChange(Rect bounds) {
- mState.mDrawable.setBounds(bounds);
- }
-
- @Override
public void draw(Canvas canvas) {
-
- if (mState.mDrawable.getLevel() == 0) {
+ final Drawable dr = getDrawable();
+ if (dr.getLevel() == 0) {
return;
}
final Rect r = mTmpRect;
final Rect bounds = getBounds();
- int level = getLevel();
+ final int level = getLevel();
+
int w = bounds.width();
final int iw = 0; //mState.mDrawable.getIntrinsicWidth();
if ((mState.mOrientation & HORIZONTAL) != 0) {
- w -= (w - iw) * (10000 - level) / 10000;
+ w -= (w - iw) * (MAX_LEVEL - level) / MAX_LEVEL;
}
+
int h = bounds.height();
final int ih = 0; //mState.mDrawable.getIntrinsicHeight();
if ((mState.mOrientation & VERTICAL) != 0) {
- h -= (h - ih) * (10000 - level) / 10000;
+ h -= (h - ih) * (MAX_LEVEL - level) / MAX_LEVEL;
}
+
final int layoutDirection = getLayoutDirection();
Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);
if (w > 0 && h > 0) {
canvas.save();
canvas.clipRect(r);
- mState.mDrawable.draw(canvas);
+ dr.draw(canvas);
canvas.restore();
}
}
- @Override
- public int getIntrinsicWidth() {
- return mState.mDrawable.getIntrinsicWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mState.mDrawable.getIntrinsicHeight();
- }
-
- @Override
- public ConstantState getConstantState() {
- if (mState.canConstantState()) {
- mState.mChangingConfigurations = getChangingConfigurations();
- return mState;
- }
- return null;
- }
-
- /** @hide */
- @Override
- public void setLayoutDirection(int layoutDirection) {
- mState.mDrawable.setLayoutDirection(layoutDirection);
- super.setLayoutDirection(layoutDirection);
- }
-
- @Override
- public Drawable mutate() {
- if (!mMutated && super.mutate() == this) {
- mState.mDrawable.mutate();
- mMutated = true;
- }
- return this;
- }
-
- /**
- * @hide
- */
- public void clearMutated() {
- super.clearMutated();
- mState.mDrawable.clearMutated();
- mMutated = false;
- }
-
- final static class ClipState extends ConstantState {
- int[] mThemeAttrs;
- int mChangingConfigurations;
-
- Drawable mDrawable;
-
+ static final class ClipState extends DrawableWrapper.DrawableWrapperState {
int mOrientation = HORIZONTAL;
int mGravity = Gravity.LEFT;
- private boolean mCheckedConstantState;
- private boolean mCanConstantState;
+ ClipState(ClipState orig) {
+ super(orig);
- 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 {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
- }
- mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
- mDrawable.setBounds(orig.mDrawable.getBounds());
- mDrawable.setLevel(orig.mDrawable.getLevel());
mOrientation = orig.mOrientation;
mGravity = orig.mGravity;
- mCheckedConstantState = mCanConstantState = true;
}
}
@Override
- public boolean canApplyTheme() {
- return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
- || super.canApplyTheme();
- }
-
- @Override
- public Drawable newDrawable() {
- return new ClipDrawable(this, null);
- }
-
- @Override
public Drawable newDrawable(Resources res) {
return new ClipDrawable(this, res);
}
-
- @Override
- public int getChangingConfigurations() {
- return mChangingConfigurations;
- }
-
- boolean canConstantState() {
- if (!mCheckedConstantState) {
- mCanConstantState = mDrawable.getConstantState() != null;
- mCheckedConstantState = true;
- }
-
- return mCanConstantState;
- }
}
private ClipDrawable(ClipState state, Resources res) {
- mState = new ClipState(state, this, res);
+ super(state, res);
+
+ mState = state;
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index c9d7869..98767a7 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -423,27 +423,41 @@ public abstract class Drawable {
* Returns the resolved layout direction for this Drawable.
*
* @return One of {@link android.view.View#LAYOUT_DIRECTION_LTR},
- * {@link android.view.View#LAYOUT_DIRECTION_RTL}
- *
- * @hide
+ * {@link android.view.View#LAYOUT_DIRECTION_RTL}
+ * @see #setLayoutDirection(int)
*/
public int getLayoutDirection() {
return mLayoutDirection;
}
/**
- * Set the layout direction for this drawable. Should be a resolved direction as the
- * Drawable as no capacity to do the resolution on his own.
+ * Set the layout direction for this drawable. Should be a resolved
+ * layout direction, as the Drawable as no capacity to do the resolution on
+ * its own.
*
- * @param layoutDirection One of {@link android.view.View#LAYOUT_DIRECTION_LTR},
- * {@link android.view.View#LAYOUT_DIRECTION_RTL}
- *
- * @hide
+ * @param layoutDirection the resolved layout direction for the drawable,
+ * either {@link android.view.View#LAYOUT_DIRECTION_LTR}
+ * or {@link android.view.View#LAYOUT_DIRECTION_RTL}
+ * @see #getLayoutDirection()
*/
- public void setLayoutDirection(@View.ResolvedLayoutDir int layoutDirection) {
- if (getLayoutDirection() != layoutDirection) {
+ public final boolean setLayoutDirection(@View.ResolvedLayoutDir int layoutDirection) {
+ if (mLayoutDirection != layoutDirection) {
mLayoutDirection = layoutDirection;
+ return onLayoutDirectionChange(layoutDirection);
}
+ return false;
+ }
+
+ /**
+ * Called when the drawable's resolved layout direction changes.
+ *
+ * @param layoutDirection the new resolved layout direction
+ * @return true if the layout direction change has caused the appearance of
+ * the drawable to change and it needs to be re-drawn
+ * @see #setLayoutDirection(int)
+ */
+ public boolean onLayoutDirectionChange(@View.ResolvedLayoutDir int layoutDirection) {
+ return false;
}
/**
@@ -554,14 +568,20 @@ public abstract class Drawable {
* Sets the bounds to which the hotspot is constrained, if they should be
* different from the drawable bounds.
*
- * @param left
- * @param top
- * @param right
- * @param bottom
+ * @param left position in pixels of the left bound
+ * @param top position in pixels of the top bound
+ * @param right position in pixels of the right bound
+ * @param bottom position in pixels of the bottom bound
+ * @see #getHotspotBounds(android.graphics.Rect)
*/
public void setHotspotBounds(int left, int top, int right, int bottom) {}
- /** @hide For internal use only. Individual results may vary. */
+ /**
+ * Populates {@code outRect} with the hotspot bounds.
+ *
+ * @param outRect the rect to populate with the hotspot bounds
+ * @see #setHotspotBounds(int, int, int, int)
+ */
public void getHotspotBounds(Rect outRect) {
outRect.set(getBounds());
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 557f563..70693f2 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -306,7 +306,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
}
- /** @hide */
@Override
public void getHotspotBounds(Rect outRect) {
if (mHotspotBounds != null) {
@@ -339,6 +338,13 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
@Override
+ public boolean onLayoutDirectionChange(int layoutDirection) {
+ // Let the container handle setting its own layout direction. Otherwise,
+ // we're accessing potentially unused states.
+ return mDrawableContainerState.setLayoutDirection(layoutDirection, getCurrentIndex());
+ }
+
+ @Override
public int getIntrinsicWidth() {
if (mDrawableContainerState.isConstantSize()) {
return mDrawableContainerState.getConstantWidth();
@@ -829,18 +835,25 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return null;
}
- final void setLayoutDirection(int layoutDirection) {
+ final boolean setLayoutDirection(int layoutDirection, int currentIndex) {
+ boolean changed = false;
+
// No need to call createAllFutures, since future drawables will
// change layout direction 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].setLayoutDirection(layoutDirection);
+ final boolean childChanged = drawables[i].setLayoutDirection(layoutDirection);
+ if (i == currentIndex) {
+ changed = childChanged;
+ }
}
}
mLayoutDirection = layoutDirection;
+
+ return changed;
}
final void applyTheme(Theme theme) {
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
new file mode 100644
index 0000000..b17bab0
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Insets;
+import android.graphics.Outline;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * Drawable container with only one child element.
+ */
+public abstract class DrawableWrapper extends Drawable implements Drawable.Callback {
+ private DrawableWrapperState mState;
+ private Drawable mDrawable;
+ private boolean mMutated;
+
+ DrawableWrapper(DrawableWrapperState state, Resources res) {
+ mState = state;
+
+ updateLocalState(res);
+ }
+
+ /**
+ * Creates a new wrapper around the specified drawable.
+ *
+ * @param dr the drawable to wrap
+ */
+ public DrawableWrapper(@Nullable Drawable dr) {
+ mState = null;
+ mDrawable = dr;
+ }
+
+ /**
+ * Initializes local dynamic properties from state. This should be called
+ * after significant state changes, e.g. from the One True Constructor and
+ * after inflating or applying a theme.
+ */
+ private void updateLocalState(Resources res) {
+ if (mState != null && mState.mDrawableState != null) {
+ final Drawable dr = mState.mDrawableState.newDrawable(res);
+ setDrawable(dr);
+ }
+ }
+
+ /**
+ * Sets the wrapped drawable.
+ *
+ * @param dr the wrapped drawable
+ */
+ public void setDrawable(@Nullable Drawable dr) {
+ if (mDrawable != null) {
+ mDrawable.setCallback(null);
+ }
+
+ mDrawable = dr;
+
+ if (dr != null) {
+ dr.setCallback(this);
+
+ // Only call setters for data that's stored in the base Drawable.
+ dr.setVisible(isVisible(), true);
+ dr.setState(getState());
+ dr.setLevel(getLevel());
+ dr.setBounds(getBounds());
+ dr.setLayoutDirection(getLayoutDirection());
+
+ if (mState != null) {
+ mState.mDrawableState = dr.getConstantState();
+ }
+ }
+
+ invalidateSelf();
+ }
+
+ /**
+ * @return the wrapped drawable
+ */
+ @Nullable
+ public Drawable getDrawable() {
+ return mDrawable;
+ }
+
+ void updateStateFromTypedArray(TypedArray a) {
+ final DrawableWrapperState 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();
+
+ // TODO: Consider using R.styleable.DrawableWrapper_drawable
+ }
+
+ @Override
+ public void applyTheme(Resources.Theme t) {
+ super.applyTheme(t);
+
+ final DrawableWrapperState state = mState;
+ if (state == null) {
+ return;
+ }
+
+ if (mDrawable != null && mDrawable.canApplyTheme()) {
+ mDrawable.applyTheme(t);
+ }
+ }
+
+ @Override
+ public boolean canApplyTheme() {
+ return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
+ }
+
+ @Override
+ public void invalidateDrawable(Drawable who) {
+ final Callback callback = getCallback();
+ if (callback != null) {
+ callback.invalidateDrawable(this);
+ }
+ }
+
+ @Override
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
+ final Callback callback = getCallback();
+ if (callback != null) {
+ callback.scheduleDrawable(this, what, when);
+ }
+ }
+
+ @Override
+ public void unscheduleDrawable(Drawable who, Runnable what) {
+ final Callback callback = getCallback();
+ if (callback != null) {
+ callback.unscheduleDrawable(this, what);
+ }
+ }
+
+ @Override
+ public void draw(@NonNull Canvas canvas) {
+ if (mDrawable != null) {
+ mDrawable.draw(canvas);
+ }
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return super.getChangingConfigurations()
+ | (mState != null ? mState.mChangingConfigurations : 0)
+ | mDrawable.getChangingConfigurations();
+ }
+
+ @Override
+ public boolean getPadding(@NonNull Rect padding) {
+ return mDrawable != null && mDrawable.getPadding(padding);
+ }
+
+ /** @hide */
+ @Override
+ public Insets getOpticalInsets() {
+ return mDrawable != null ? mDrawable.getOpticalInsets() : Insets.NONE;
+ }
+
+ @Override
+ public void setHotspot(float x, float y) {
+ if (mDrawable != null) {
+ mDrawable.setHotspot(x, y);
+ }
+ }
+
+ @Override
+ public void setHotspotBounds(int left, int top, int right, int bottom) {
+ if (mDrawable != null) {
+ mDrawable.setHotspotBounds(left, top, right, bottom);
+ }
+ }
+
+ @Override
+ public void getHotspotBounds(@NonNull Rect outRect) {
+ if (mDrawable != null) {
+ mDrawable.getHotspotBounds(outRect);
+ } else {
+ outRect.set(getBounds());
+ }
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ final boolean superChanged = super.setVisible(visible, restart);
+ final boolean changed = mDrawable != null && mDrawable.setVisible(visible, restart);
+ return superChanged | changed;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ if (mDrawable != null) {
+ mDrawable.setAlpha(alpha);
+ }
+ }
+
+ @Override
+ public int getAlpha() {
+ return mDrawable != null ? mDrawable.getAlpha() : 255;
+ }
+
+ @Override
+ public void setColorFilter(@Nullable ColorFilter cf) {
+ if (mDrawable != null) {
+ mDrawable.setColorFilter(cf);
+ }
+ }
+
+ @Override
+ public void setTintList(@Nullable ColorStateList tint) {
+ if (mDrawable != null) {
+ mDrawable.setTintList(tint);
+ }
+ }
+
+ @Override
+ public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+ if (mDrawable != null) {
+ mDrawable.setTintMode(tintMode);
+ }
+ }
+
+ @Override
+ public boolean onLayoutDirectionChange(@View.ResolvedLayoutDir int layoutDirection) {
+ return mDrawable != null && mDrawable.setLayoutDirection(layoutDirection);
+ }
+
+ @Override
+ public int getOpacity() {
+ return mDrawable != null ? mDrawable.getOpacity() : PixelFormat.TRANSPARENT;
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mDrawable != null && mDrawable.isStateful();
+ }
+
+ @Override
+ protected boolean onStateChange(int[] state) {
+ if (mDrawable != null) {
+ final boolean changed = mDrawable.setState(state);
+ if (changed) {
+ onBoundsChange(getBounds());
+ }
+ return changed;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean onLevelChange(int level) {
+ return mDrawable != null && mDrawable.setLevel(level);
+ }
+
+ @Override
+ protected void onBoundsChange(@NonNull Rect bounds) {
+ if (mDrawable != null) {
+ mDrawable.setBounds(bounds);
+ }
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mDrawable != null ? mDrawable.getIntrinsicWidth() : -1;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mDrawable != null ? mDrawable.getIntrinsicHeight() : -1;
+ }
+
+ @Override
+ public void getOutline(@NonNull Outline outline) {
+ if (mDrawable != null) {
+ mDrawable.getOutline(outline);
+ } else {
+ super.getOutline(outline);
+ }
+ }
+
+ @Override
+ @Nullable
+ public ConstantState getConstantState() {
+ if (mState != null && mState.canConstantState()) {
+ mState.mChangingConfigurations = getChangingConfigurations();
+ return mState;
+ }
+ return null;
+ }
+
+ @Override
+ @NonNull
+ public Drawable mutate() {
+ if (!mMutated && super.mutate() == this) {
+ mState = mutateConstantState();
+ if (mDrawable != null) {
+ mDrawable.mutate();
+ }
+ if (mState != null) {
+ mState.mDrawableState = mDrawable != null ? mDrawable.getConstantState() : null;
+ }
+ mMutated = true;
+ }
+ return this;
+ }
+
+ /**
+ * Mutates the constant state and returns the new state. Responsible for
+ * updating any local copy.
+ * <p>
+ * This method should never call the super implementation; it should always
+ * mutate and return its own constant state.
+ *
+ * @return the new state
+ */
+ DrawableWrapperState mutateConstantState() {
+ return mState;
+ }
+
+ /**
+ * @hide Only used by the framework for pre-loading resources.
+ */
+ public void clearMutated() {
+ super.clearMutated();
+ if (mDrawable != null) {
+ mDrawable.clearMutated();
+ }
+ mMutated = false;
+ }
+
+ /**
+ * Called during inflation to inflate the child element.
+ */
+ void inflateChildDrawable(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Resources.Theme theme) throws XmlPullParserException, IOException {
+ // Drawable specified on the root element takes precedence.
+ if (getDrawable() != null) {
+ return;
+ }
+
+ // Seek to the first child element.
+ 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) {
+ dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
+ break;
+ }
+ }
+
+ if (dr != null) {
+ setDrawable(dr);
+ }
+ }
+
+ abstract static class DrawableWrapperState extends Drawable.ConstantState {
+ int[] mThemeAttrs;
+ int mChangingConfigurations;
+
+ Drawable.ConstantState mDrawableState;
+
+ DrawableWrapperState(DrawableWrapperState orig) {
+ if (orig != null) {
+ mThemeAttrs = orig.mThemeAttrs;
+ mChangingConfigurations = orig.mChangingConfigurations;
+ mDrawableState = orig.mDrawableState;
+ }
+ }
+
+ @Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null
+ || (mDrawableState != null && mDrawableState.canApplyTheme())
+ || super.canApplyTheme();
+ }
+
+ @Override
+ public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+ final Drawable.ConstantState state = mDrawableState;
+ if (state != null) {
+ return state.addAtlasableBitmaps(atlasList);
+ }
+ return 0;
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return newDrawable(null);
+ }
+
+ @Override
+ public abstract Drawable newDrawable(Resources res);
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+
+ public boolean canConstantState() {
+ return mDrawableState != null;
+ }
+ }
+}
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 50a6df4..b0cd386 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -18,27 +18,20 @@ package android.graphics.drawable;
import com.android.internal.R;
-import android.annotation.NonNull;
-
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import android.content.res.ColorStateList;
+import android.annotation.NonNull;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
+import android.content.res.TypedArray;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
import java.io.IOException;
-import java.util.Collection;
/**
* A Drawable that insets another Drawable by a specified distance.
@@ -56,13 +49,10 @@ import java.util.Collection;
* @attr ref android.R.styleable#InsetDrawable_insetTop
* @attr ref android.R.styleable#InsetDrawable_insetBottom
*/
-public class InsetDrawable extends Drawable implements Drawable.Callback {
+public class InsetDrawable extends DrawableWrapper {
private final Rect mTmpRect = new Rect();
private InsetState mState;
- private Drawable mDrawable;
-
- private boolean mMutated;
/**
* No-arg constructor used by drawable inflation.
@@ -94,72 +84,29 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
int insetBottom) {
this(new InsetState(), null);
- mState.mDrawableState = drawable == null ? null : drawable.getConstantState();
mState.mInsetLeft = insetLeft;
mState.mInsetTop = insetTop;
mState.mInsetRight = insetRight;
mState.mInsetBottom = insetBottom;
- mDrawable = drawable;
-
- if (drawable != null) {
- drawable.setCallback(this);
- }
+ setDrawable(drawable);
}
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
- final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.InsetDrawable);
- super.inflateWithAttributes(r, parser, a, R.styleable.InsetDrawable_visible);
+ super.inflate(r, parser, attrs, theme);
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.InsetDrawable);
updateStateFromTypedArray(a);
- inflateChildElements(r, parser, attrs, theme);
+ inflateChildDrawable(r, parser, attrs, theme);
verifyRequiredAttributes(a);
a.recycle();
}
- private void setDrawable(Drawable dr) {
- if (mDrawable != null) {
- mDrawable.setCallback(null);
- }
-
- mDrawable = dr;
-
- if (dr != null) {
- dr.setCallback(this);
- dr.setVisible(isVisible(), true);
- dr.setState(getState());
- dr.setLevel(getLevel());
- dr.setBounds(getBounds());
- dr.setLayoutDirection(getLayoutDirection());
- }
- }
-
- private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
- Theme theme) throws XmlPullParserException, IOException {
- // Load inner XML elements.
- if (mDrawable == null) {
- int type;
- while ((type=parser.next()) == XmlPullParser.TEXT) {
- }
- if (type != XmlPullParser.START_TAG) {
- throw new XmlPullParserException(parser.getPositionDescription()
- + ": <inset> tag requires a 'drawable' attribute or "
- + "child tag defining a drawable");
- }
-
- final Drawable dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
- if (dr != null) {
- mState.mDrawableState = dr.getConstantState();
- setDrawable(dr);
- }
- }
- }
-
private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
// If we're not waiting on a theme, verify required attributes.
- if (mDrawable == null && (mState.mThemeAttrs == null
+ if (getDrawable() == null && (mState.mThemeAttrs == null
|| mState.mThemeAttrs[R.styleable.InsetDrawable_drawable] == 0)) {
throw new XmlPullParserException(a.getPositionDescription()
+ ": <inset> tag requires a 'drawable' attribute or "
@@ -167,15 +114,11 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
}
- private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
- final InsetState state = mState;
-
- // Account for any configuration changes.
- state.mChangingConfigurations |= a.getChangingConfigurations();
-
- // Extract the theme attributes, if any.
- state.mThemeAttrs = a.extractThemeAttrs();
+ @Override
+ void updateStateFromTypedArray(TypedArray a) {
+ super.updateStateFromTypedArray(a);
+ final InsetState state = mState;
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
final int attr = a.getIndex(i);
@@ -183,7 +126,6 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
case R.styleable.InsetDrawable_drawable:
final Drawable dr = a.getDrawable(attr);
if (dr != null) {
- mState.mDrawableState = dr.getConstantState();
setDrawable(dr);
}
break;
@@ -214,8 +156,6 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
@Override
public void applyTheme(Theme t) {
- super.applyTheme(t);
-
final InsetState state = mState;
if (state == null) {
return;
@@ -233,55 +173,14 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
}
- if (mDrawable != null && mDrawable.canApplyTheme()) {
- mDrawable.applyTheme(t);
- }
- }
-
- @Override
- public boolean canApplyTheme() {
- return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
- }
-
- @Override
- public void invalidateDrawable(Drawable who) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.invalidateDrawable(this);
- }
- }
-
- @Override
- public void scheduleDrawable(Drawable who, Runnable what, long when) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.scheduleDrawable(this, what, when);
- }
- }
-
- @Override
- public void unscheduleDrawable(Drawable who, Runnable what) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.unscheduleDrawable(this, what);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- mDrawable.draw(canvas);
- }
-
- @Override
- public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mState.mChangingConfigurations
- | mDrawable.getChangingConfigurations();
+ // The drawable may have changed as a result of applying the theme, so
+ // apply the theme to the wrapped drawable last.
+ super.applyTheme(t);
}
@Override
public boolean getPadding(Rect padding) {
- final boolean pad = mDrawable.getPadding(padding);
+ final boolean pad = super.getPadding(padding);
padding.left += mState.mInsetLeft;
padding.right += mState.mInsetRight;
@@ -303,62 +202,9 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public void setHotspot(float x, float y) {
- mDrawable.setHotspot(x, y);
- }
-
- @Override
- public void setHotspotBounds(int left, int top, int right, int bottom) {
- mDrawable.setHotspotBounds(left, top, right, bottom);
- }
-
- /** @hide */
- @Override
- public void getHotspotBounds(Rect outRect) {
- mDrawable.getHotspotBounds(outRect);
- }
-
- @Override
- public boolean setVisible(boolean visible, boolean restart) {
- mDrawable.setVisible(visible, restart);
- return super.setVisible(visible, restart);
- }
-
- @Override
- public void setAlpha(int alpha) {
- mDrawable.setAlpha(alpha);
- }
-
- @Override
- public int getAlpha() {
- return mDrawable.getAlpha();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- mDrawable.setColorFilter(cf);
- }
-
- @Override
- public void setTintList(ColorStateList tint) {
- mDrawable.setTintList(tint);
- }
-
- @Override
- public void setTintMode(Mode tintMode) {
- mDrawable.setTintMode(tintMode);
- }
-
- /** {@hide} */
- @Override
- public void setLayoutDirection(int layoutDirection) {
- mDrawable.setLayoutDirection(layoutDirection);
- }
-
- @Override
public int getOpacity() {
final InsetState state = mState;
- final int opacity = mDrawable.getOpacity();
+ final int opacity = getDrawable().getOpacity();
if (opacity == PixelFormat.OPAQUE && (state.mInsetLeft > 0 || state.mInsetTop > 0
|| state.mInsetRight > 0 || state.mInsetBottom > 0)) {
return PixelFormat.TRANSLUCENT;
@@ -367,23 +213,6 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public boolean isStateful() {
- return mDrawable.isStateful();
- }
-
- @Override
- protected boolean onStateChange(int[] state) {
- final boolean changed = mDrawable.setState(state);
- onBoundsChange(getBounds());
- return changed;
- }
-
- @Override
- protected boolean onLevelChange(int level) {
- return mDrawable.setLevel(level);
- }
-
- @Override
protected void onBoundsChange(Rect bounds) {
final Rect r = mTmpRect;
r.set(bounds);
@@ -393,22 +222,23 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
r.right -= mState.mInsetRight;
r.bottom -= mState.mInsetBottom;
- mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
+ // Apply inset bounds to the wrapped drawable.
+ super.onBoundsChange(r);
}
@Override
public int getIntrinsicWidth() {
- return mDrawable.getIntrinsicWidth() + mState.mInsetLeft + mState.mInsetRight;
+ return getDrawable().getIntrinsicWidth() + mState.mInsetLeft + mState.mInsetRight;
}
@Override
public int getIntrinsicHeight() {
- return mDrawable.getIntrinsicHeight() + mState.mInsetTop + mState.mInsetBottom;
+ return getDrawable().getIntrinsicHeight() + mState.mInsetTop + mState.mInsetBottom;
}
@Override
public void getOutline(@NonNull Outline outline) {
- mDrawable.getOutline(outline);
+ getDrawable().getOutline(outline);
}
@Override
@@ -421,33 +251,12 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public Drawable mutate() {
- if (!mMutated && super.mutate() == this) {
- mState = new InsetState(mState);
- mDrawable.mutate();
- mState.mDrawableState = mDrawable.getConstantState();
- mMutated = true;
- }
- return this;
+ DrawableWrapperState mutateConstantState() {
+ mState = new InsetState(mState);
+ return mState;
}
- /**
- * @hide
- */
- public void clearMutated() {
- super.clearMutated();
- mDrawable.clearMutated();
- mMutated = false;
- }
-
- /**
- * Returns the drawable wrapped by this InsetDrawable. May be null.
- */
- public Drawable getDrawable() {
- return mDrawable;
- }
-
- private static final class InsetState extends ConstantState {
+ static final class InsetState extends DrawableWrapper.DrawableWrapperState {
int[] mThemeAttrs;
int mChangingConfigurations;
@@ -458,15 +267,14 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
int mInsetRight = 0;
int mInsetBottom = 0;
- public InsetState() {
- // Empty constructor.
+ InsetState() {
+ this(null);
}
- public InsetState(InsetState orig) {
+ InsetState(InsetState orig) {
+ super(orig);
+
if (orig != null) {
- mThemeAttrs = orig.mThemeAttrs;
- mChangingConfigurations = orig.mChangingConfigurations;
- mDrawableState = orig.mDrawableState;
mInsetLeft = orig.mInsetLeft;
mInsetTop = orig.mInsetTop;
mInsetRight = orig.mInsetRight;
@@ -475,39 +283,9 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public boolean canApplyTheme() {
- return mThemeAttrs != null
- || (mDrawableState != null && mDrawableState.canApplyTheme())
- || super.canApplyTheme();
- }
-
- @Override
- public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
- final ConstantState state = mDrawableState;
- if (state != null) {
- return state.addAtlasableBitmaps(atlasList);
- }
- return 0;
- }
-
- @Override
- public Drawable newDrawable() {
- return new InsetDrawable(this, null);
- }
-
- @Override
public Drawable newDrawable(Resources res) {
return new InsetDrawable(this, res);
}
-
- @Override
- public int getChangingConfigurations() {
- return mChangingConfigurations;
- }
-
- public boolean canConstantState() {
- return mDrawableState != null;
- }
}
/**
@@ -515,21 +293,9 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
* constructors to set the state and initialize local properties.
*/
private InsetDrawable(InsetState state, Resources res) {
- mState = state;
-
- updateLocalState(res);
- }
+ super(state, res);
- /**
- * Initializes local dynamic properties from state. This should be called
- * after significant state changes, e.g. from the One True Constructor and
- * after inflating or applying a theme.
- */
- private void updateLocalState(Resources res) {
- if (mState.mDrawableState != null) {
- final Drawable dr = mState.mDrawableState.newDrawable(res);
- setDrawable(dr);
- }
+ mState = state;
}
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 616aebd..08849df 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -834,7 +834,6 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
}
- /** @hide */
@Override
public void getHotspotBounds(Rect outRect) {
if (mHotspotBounds != null) {
@@ -1230,16 +1229,16 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
mMutated = false;
}
- /** @hide */
@Override
- public void setLayoutDirection(int layoutDirection) {
- super.setLayoutDirection(layoutDirection);
+ public boolean onLayoutDirectionChange(int layoutDirection) {
+ boolean changed = false;
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setLayoutDirection(layoutDirection);
+ changed |= array[i].mDrawable.setLayoutDirection(layoutDirection);
}
updateLayerBounds(getBounds());
+ return changed;
}
static class ChildDrawable {
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 556c59f..c6ea91d 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -614,7 +614,6 @@ public class RippleDrawable extends LayerDrawable {
onHotspotBoundsChanged();
}
- /** @hide */
@Override
public void getHotspotBounds(Rect outRect) {
outRect.set(mHotspotBounds);
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index e1991fe..595061c 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -29,6 +29,7 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
+import android.util.MathUtils;
import android.util.TypedValue;
import android.util.AttributeSet;
@@ -51,12 +52,10 @@ import java.io.IOException;
* @attr ref android.R.styleable#RotateDrawable_pivotY
* @attr ref android.R.styleable#RotateDrawable_drawable
*/
-public class RotateDrawable extends Drawable implements Drawable.Callback {
- private static final float MAX_LEVEL = 10000.0f;
+public class RotateDrawable extends DrawableWrapper {
+ private static final int MAX_LEVEL = 10000;
- private final RotateState mState;
-
- private boolean mMutated;
+ private RotateState mState;
/**
* Create a new rotating drawable with an empty state.
@@ -65,100 +64,108 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
this(null, null);
}
- /**
- * Create a new rotating drawable with the specified state. A copy of
- * this state is used as the internal state for the newly created
- * drawable.
- *
- * @param rotateState the state for this drawable
- */
- private RotateDrawable(RotateState rotateState, Resources res) {
- mState = new RotateState(rotateState, this, res);
- }
-
@Override
- public void draw(Canvas canvas) {
- final RotateState st = mState;
- final Drawable d = st.mDrawable;
- final Rect bounds = d.getBounds();
- final int w = bounds.right - bounds.left;
- final int h = bounds.bottom - bounds.top;
- final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
- final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
+ public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
+ throws XmlPullParserException, IOException {
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.RotateDrawable);
+ super.inflateWithAttributes(r, parser, a, R.styleable.RotateDrawable_visible);
- final int saveCount = canvas.save();
- canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
- d.draw(canvas);
- canvas.restoreToCount(saveCount);
+ updateStateFromTypedArray(a);
+ inflateChildDrawable(r, parser, attrs, theme);
+ verifyRequiredAttributes(a);
+ a.recycle();
}
- /**
- * Sets the drawable rotated by this RotateDrawable.
- *
- * @param drawable The drawable to rotate
- */
- public void setDrawable(Drawable drawable) {
- final Drawable oldDrawable = mState.mDrawable;
- if (oldDrawable != drawable) {
- if (oldDrawable != null) {
- oldDrawable.setCallback(null);
- }
- mState.mDrawable = drawable;
- 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 (getDrawable() == null && (mState.mThemeAttrs == null
+ || mState.mThemeAttrs[R.styleable.RotateDrawable_drawable] == 0)) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + ": <rotate> tag requires a 'drawable' attribute or "
+ + "child tag defining a drawable");
}
}
- /**
- * @return The drawable rotated by this RotateDrawable
- */
- public Drawable getDrawable() {
- return mState.mDrawable;
- }
-
@Override
- public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mState.mChangingConfigurations
- | mState.mDrawable.getChangingConfigurations();
- }
+ void updateStateFromTypedArray(TypedArray a) {
+ super.updateStateFromTypedArray(a);
- @Override
- public void setAlpha(int alpha) {
- mState.mDrawable.setAlpha(alpha);
- }
+ final RotateState state = mState;
- @Override
- public int getAlpha() {
- return mState.mDrawable.getAlpha();
- }
+ // Account for any configuration changes.
+ state.mChangingConfigurations |= a.getChangingConfigurations();
- @Override
- public void setColorFilter(ColorFilter cf) {
- mState.mDrawable.setColorFilter(cf);
- }
+ // Extract the theme attributes, if any.
+ state.mThemeAttrs = a.extractThemeAttrs();
- @Override
- public void setTintList(ColorStateList tint) {
- mState.mDrawable.setTintList(tint);
+ 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 (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();
+ }
+
+ state.mFromDegrees = a.getFloat(
+ R.styleable.RotateDrawable_fromDegrees, state.mFromDegrees);
+ state.mToDegrees = a.getFloat(
+ R.styleable.RotateDrawable_toDegrees, state.mToDegrees);
+ state.mCurrentDegrees = state.mFromDegrees;
+
+ final Drawable dr = a.getDrawable(R.styleable.RotateDrawable_drawable);
+ if (dr != null) {
+ setDrawable(dr);
+ }
}
@Override
- public void setTintMode(Mode tintMode) {
- mState.mDrawable.setTintMode(tintMode);
+ public void applyTheme(Theme t) {
+ final RotateState state = mState;
+ if (state == null) {
+ return;
+ }
+
+ if (state.mThemeAttrs != null) {
+ 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();
+ }
+ }
+
+ // The drawable may have changed as a result of applying the theme, so
+ // apply the theme to the wrapped drawable last.
+ super.applyTheme(t);
}
@Override
- public int getOpacity() {
- return mState.mDrawable.getOpacity();
+ public void draw(Canvas canvas) {
+ final Drawable d = getDrawable();
+ final Rect bounds = d.getBounds();
+ final int w = bounds.right - bounds.left;
+ final int h = bounds.bottom - bounds.top;
+ final RotateState st = mState;
+ final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
+ final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
+
+ final int saveCount = canvas.save();
+ canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
+ d.draw(canvas);
+ canvas.restoreToCount(saveCount);
}
/**
* Sets the start angle for rotation.
*
- * @param fromDegrees Starting angle in degrees
- *
+ * @param fromDegrees starting angle in degrees
* @see #getFromDegrees()
* @attr ref android.R.styleable#RotateDrawable_fromDegrees
*/
@@ -170,8 +177,7 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
}
/**
- * @return The starting angle for rotation in degrees
- *
+ * @return starting angle for rotation in degrees
* @see #setFromDegrees(float)
* @attr ref android.R.styleable#RotateDrawable_fromDegrees
*/
@@ -182,8 +188,7 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
/**
* Sets the end angle for rotation.
*
- * @param toDegrees Ending angle in degrees
- *
+ * @param toDegrees ending angle in degrees
* @see #getToDegrees()
* @attr ref android.R.styleable#RotateDrawable_toDegrees
*/
@@ -195,8 +200,7 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
}
/**
- * @return The ending angle for rotation in degrees
- *
+ * @return ending angle for rotation in degrees
* @see #setToDegrees(float)
* @attr ref android.R.styleable#RotateDrawable_toDegrees
*/
@@ -211,7 +215,6 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
* relative, the position represents a fraction of the drawable
* width. Otherwise, the position represents an absolute value in
* pixels.
- *
* @see #setPivotXRelative(boolean)
* @attr ref android.R.styleable#RotateDrawable_pivotX
*/
@@ -224,7 +227,6 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
/**
* @return X position around which to rotate
- *
* @see #setPivotX(float)
* @attr ref android.R.styleable#RotateDrawable_pivotX
*/
@@ -236,9 +238,8 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
* Sets whether the X pivot value represents a fraction of the drawable
* width or an absolute value in pixels.
*
- * @param relative True if the X pivot represents a fraction of the drawable
+ * @param relative true if the X pivot represents a fraction of the drawable
* width, or false if it represents an absolute value in pixels
- *
* @see #isPivotXRelative()
*/
public void setPivotXRelative(boolean relative) {
@@ -249,9 +250,8 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
}
/**
- * @return True if the X pivot represents a fraction of the drawable width,
+ * @return true if the X pivot represents a fraction of the drawable width,
* or false if it represents an absolute value in pixels
- *
* @see #setPivotXRelative(boolean)
*/
public boolean isPivotXRelative() {
@@ -265,7 +265,6 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
* relative, the position represents a fraction of the drawable
* height. Otherwise, the position represents an absolute value
* in pixels.
- *
* @see #getPivotY()
* @attr ref android.R.styleable#RotateDrawable_pivotY
*/
@@ -278,7 +277,6 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
/**
* @return Y position around which to rotate
- *
* @see #setPivotY(float)
* @attr ref android.R.styleable#RotateDrawable_pivotY
*/
@@ -292,7 +290,6 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
*
* @param relative True if the Y pivot represents a fraction of the drawable
* height, or false if it represents an absolute value in pixels
- *
* @see #isPivotYRelative()
*/
public void setPivotYRelative(boolean relative) {
@@ -303,9 +300,8 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
}
/**
- * @return True if the Y pivot represents a fraction of the drawable height,
+ * @return true if the Y pivot represents a fraction of the drawable height,
* or false if it represents an absolute value in pixels
- *
* @see #setPivotYRelative(boolean)
*/
public boolean isPivotYRelative() {
@@ -313,254 +309,36 @@ 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) {
- callback.invalidateDrawable(this);
- }
- }
-
- @Override
- public void scheduleDrawable(Drawable who, Runnable what, long when) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.scheduleDrawable(this, what, when);
- }
- }
-
- @Override
- public void unscheduleDrawable(Drawable who, Runnable what) {
- final Callback callback = getCallback();
- if (callback != null) {
- callback.unscheduleDrawable(this, what);
- }
- }
-
- @Override
- public boolean getPadding(Rect padding) {
- return mState.mDrawable.getPadding(padding);
- }
-
- @Override
- public boolean setVisible(boolean visible, boolean restart) {
- mState.mDrawable.setVisible(visible, restart);
- return super.setVisible(visible, restart);
- }
-
- @Override
- public boolean isStateful() {
- return mState.mDrawable.isStateful();
- }
-
- @Override
- protected boolean onStateChange(int[] state) {
- final boolean changed = mState.mDrawable.setState(state);
- onBoundsChange(getBounds());
- return changed;
- }
-
- @Override
protected boolean onLevelChange(int level) {
- mState.mDrawable.setLevel(level);
- onBoundsChange(getBounds());
+ super.onLevelChange(level);
- mState.mCurrentDegrees = mState.mFromDegrees +
- (mState.mToDegrees - mState.mFromDegrees) *
- (level / MAX_LEVEL);
+ final float value = level / (float) MAX_LEVEL;
+ final float degrees = MathUtils.lerp(mState.mFromDegrees, mState.mToDegrees, value);
+ mState.mCurrentDegrees = degrees;
invalidateSelf();
return true;
}
@Override
- protected void onBoundsChange(Rect bounds) {
- mState.mDrawable.setBounds(bounds.left, bounds.top,
- bounds.right, bounds.bottom);
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mState.mDrawable.getIntrinsicWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mState.mDrawable.getIntrinsicHeight();
- }
-
- @Override
- public ConstantState getConstantState() {
- if (mState.canConstantState()) {
- mState.mChangingConfigurations = getChangingConfigurations();
- return mState;
- }
- return null;
- }
-
- @Override
- public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
- throws XmlPullParserException, IOException {
- final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.RotateDrawable);
- super.inflateWithAttributes(r, parser, a, R.styleable.RotateDrawable_visible);
-
- // 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 RotateState state = mState;
- if (state == null) {
- return;
- }
-
- if (state.mThemeAttrs != null) {
- 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();
- }
- }
-
- 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;
- }
- dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
- }
-
- 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.ScaleDrawable_drawable] == 0)) {
- throw new XmlPullParserException(a.getPositionDescription()
- + ": <rotate> tag requires a 'drawable' attribute or "
- + "child tag defining a drawable");
- }
- }
-
- private void updateStateFromTypedArray(TypedArray a) {
- final RotateState 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.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 (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();
- }
-
- state.mFromDegrees = a.getFloat(R.styleable.RotateDrawable_fromDegrees, state.mFromDegrees);
- state.mToDegrees = a.getFloat(R.styleable.RotateDrawable_toDegrees, state.mToDegrees);
- state.mCurrentDegrees = state.mFromDegrees;
-
- final Drawable dr = a.getDrawable(R.styleable.RotateDrawable_drawable);
- if (dr != null) {
- state.mDrawable = dr;
- dr.setCallback(this);
- }
- }
-
- @Override
- public Drawable mutate() {
- if (!mMutated && super.mutate() == this) {
- mState.mDrawable.mutate();
- mMutated = true;
- }
- return this;
- }
-
- /**
- * @hide
- */
- public void clearMutated() {
- super.clearMutated();
- mState.mDrawable.clearMutated();
- mMutated = false;
+ DrawableWrapperState mutateConstantState() {
+ mState = new RotateState(mState);
+ return mState;
}
- /**
- * 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.
- */
- final static class RotateState extends Drawable.ConstantState {
- int[] mThemeAttrs;
- int mChangingConfigurations;
-
- Drawable mDrawable;
-
+ static final class RotateState extends DrawableWrapper.DrawableWrapperState {
boolean mPivotXRel = true;
float mPivotX = 0.5f;
boolean mPivotYRel = true;
float mPivotY = 0.5f;
-
float mFromDegrees = 0.0f;
float mToDegrees = 360.0f;
-
float mCurrentDegrees = 0.0f;
- private boolean mCheckedConstantState;
- private boolean mCanConstantState;
+ RotateState(RotateState orig) {
+ super(orig);
- 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 {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
- }
- mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
- mDrawable.setBounds(orig.mDrawable.getBounds());
- mDrawable.setLevel(orig.mDrawable.getLevel());
mPivotXRel = orig.mPivotXRel;
mPivotX = orig.mPivotX;
mPivotYRel = orig.mPivotYRel;
@@ -568,38 +346,18 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
mFromDegrees = orig.mFromDegrees;
mToDegrees = orig.mToDegrees;
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);
- }
-
- @Override
public Drawable newDrawable(Resources res) {
return new RotateDrawable(this, res);
}
+ }
- @Override
- public int getChangingConfigurations() {
- return mChangingConfigurations;
- }
-
- public boolean canConstantState() {
- if (!mCheckedConstantState) {
- mCanConstantState = mDrawable.getConstantState() != null;
- mCheckedConstantState = true;
- }
+ private RotateDrawable(RotateState state, Resources res) {
+ super(state, res);
- return mCanConstantState;
- }
+ mState = state;
}
}
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index da722f3..0acbeda 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -21,17 +21,17 @@ import com.android.internal.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
-import android.graphics.*;
-import android.graphics.PorterDuff.Mode;
-import android.view.Gravity;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
import java.io.IOException;
-import java.util.Collection;
/**
* A Drawable that changes the size of another Drawable based on its current
@@ -49,44 +49,37 @@ import java.util.Collection;
* @attr ref android.R.styleable#ScaleDrawable_scaleGravity
* @attr ref android.R.styleable#ScaleDrawable_drawable
*/
-public class ScaleDrawable extends Drawable implements Drawable.Callback {
- private ScaleState mState;
- private boolean mMutated;
+public class ScaleDrawable extends DrawableWrapper {
+ private static final int MAX_LEVEL = 10000;
+
private final Rect mTmpRect = new Rect();
+ private ScaleState mState;
+
ScaleDrawable() {
- this(null, null);
+ this(new ScaleState(null), null);
}
+ /**
+ * Creates a new scale drawable with the specified gravity and scale
+ * properties.
+ *
+ * @param drawable the drawable to scale
+ * @param gravity gravity constant (see {@link Gravity} used to position
+ * the scaled drawable within the parent container
+ * @param scaleWidth width scaling factor [0...1] to use then the level is
+ * at the maximum value, or -1 to not scale width
+ * @param scaleHeight height scaling factor [0...1] to use then the level
+ * is at the maximum value, or -1 to not scale height
+ */
public ScaleDrawable(Drawable drawable, int gravity, float scaleWidth, float scaleHeight) {
- this(null, null);
+ this(new ScaleState(null), null);
- mState.mDrawable = drawable;
mState.mGravity = gravity;
mState.mScaleWidth = scaleWidth;
mState.mScaleHeight = scaleHeight;
- if (drawable != null) {
- drawable.setCallback(this);
- }
- }
-
- /**
- * Returns the drawable scaled by this ScaleDrawable.
- */
- public Drawable getDrawable() {
- return mState.mDrawable;
- }
-
- 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 defaultValue;
+ setDrawable(drawable);
}
@Override
@@ -95,65 +88,15 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
super.inflate(r, parser, attrs, theme);
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ScaleDrawable);
-
- // 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);
+ inflateChildDrawable(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)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
- }
-
- 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
+ if (getDrawable() == null && (mState.mThemeAttrs == null
|| mState.mThemeAttrs[R.styleable.ScaleDrawable_drawable] == 0)) {
throw new XmlPullParserException(a.getPositionDescription()
+ ": <scale> tag requires a 'drawable' attribute or "
@@ -161,127 +104,95 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
}
}
- 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();
+ @Override
+ void updateStateFromTypedArray(TypedArray a) {
+ super.updateStateFromTypedArray(a);
- 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, state.mGravity);
+ final ScaleState state = mState;
+ 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, state.mGravity);
state.mUseIntrinsicSizeAsMin = a.getBoolean(
R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, state.mUseIntrinsicSizeAsMin);
final Drawable dr = a.getDrawable(R.styleable.ScaleDrawable_drawable);
if (dr != null) {
- state.mDrawable = dr;
- dr.setCallback(this);
- }
- }
-
- @Override
- public boolean canApplyTheme() {
- return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
- }
-
- // overrides from Drawable.Callback
-
- public void invalidateDrawable(Drawable who) {
- if (getCallback() != null) {
- getCallback().invalidateDrawable(this);
+ setDrawable(dr);
}
}
- public void scheduleDrawable(Drawable who, Runnable what, long when) {
- if (getCallback() != null) {
- getCallback().scheduleDrawable(this, what, when);
+ private static float getPercent(TypedArray a, int index, float defaultValue) {
+ final int type = a.getType(index);
+ if (type == TypedValue.TYPE_FRACTION || type == TypedValue.TYPE_NULL) {
+ return a.getFraction(index, 1, 1, defaultValue);
}
- }
- public void unscheduleDrawable(Drawable who, Runnable what) {
- if (getCallback() != null) {
- getCallback().unscheduleDrawable(this, what);
+ // Coerce to float.
+ final String s = a.getString(index);
+ if (s != null) {
+ if (s.endsWith("%")) {
+ final String f = s.substring(0, s.length() - 1);
+ return Float.parseFloat(f) / 100.0f;
+ }
}
- }
-
- // overrides from Drawable
-
- @Override
- public void draw(Canvas canvas) {
- if (mState.mDrawable.getLevel() != 0)
- mState.mDrawable.draw(canvas);
- }
- @Override
- public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mState.mChangingConfigurations
- | mState.mDrawable.getChangingConfigurations();
- }
-
- @Override
- public boolean getPadding(Rect padding) {
- // XXX need to adjust padding!
- return mState.mDrawable.getPadding(padding);
- }
-
- @Override
- public boolean setVisible(boolean visible, boolean restart) {
- mState.mDrawable.setVisible(visible, restart);
- return super.setVisible(visible, restart);
- }
-
- @Override
- public void setAlpha(int alpha) {
- mState.mDrawable.setAlpha(alpha);
+ return defaultValue;
}
@Override
- public int getAlpha() {
- return mState.mDrawable.getAlpha();
- }
+ public void applyTheme(Theme t) {
+ final ScaleState state = mState;
+ if (state == null) {
+ return;
+ }
- @Override
- public void setColorFilter(ColorFilter cf) {
- mState.mDrawable.setColorFilter(cf);
- }
+ 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();
+ }
+ }
- @Override
- public void setTintList(ColorStateList tint) {
- mState.mDrawable.setTintList(tint);
+ // The drawable may have changed as a result of applying the theme, so
+ // apply the theme to the wrapped drawable last.
+ super.applyTheme(t);
}
@Override
- public void setTintMode(Mode tintMode) {
- mState.mDrawable.setTintMode(tintMode);
+ public void draw(Canvas canvas) {
+ final Drawable d = getDrawable();
+ if (d != null && d.getLevel() != 0) {
+ d.draw(canvas);
+ }
}
@Override
public int getOpacity() {
- return mState.mDrawable.getOpacity();
- }
+ final Drawable d = getDrawable();
+ if (d.getLevel() == 0) {
+ return PixelFormat.TRANSPARENT;
+ }
- @Override
- public boolean isStateful() {
- return mState.mDrawable.isStateful();
- }
+ final int opacity = d.getOpacity();
+ if (opacity == PixelFormat.OPAQUE && d.getLevel() < MAX_LEVEL) {
+ return PixelFormat.TRANSLUCENT;
+ }
- @Override
- protected boolean onStateChange(int[] state) {
- boolean changed = mState.mDrawable.setState(state);
- onBoundsChange(getBounds());
- return changed;
+ return opacity;
}
@Override
protected boolean onLevelChange(int level) {
- mState.mDrawable.setLevel(level);
+ super.onLevelChange(level);
onBoundsChange(getBounds());
invalidateSelf();
return true;
@@ -289,144 +200,67 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
@Override
protected void onBoundsChange(Rect bounds) {
+ final Drawable d = getDrawable();
final Rect r = mTmpRect;
final boolean min = mState.mUseIntrinsicSizeAsMin;
- int level = getLevel();
+ final int level = getLevel();
+
int w = bounds.width();
if (mState.mScaleWidth > 0) {
- final int iw = min ? mState.mDrawable.getIntrinsicWidth() : 0;
- w -= (int) ((w - iw) * (10000 - level) * mState.mScaleWidth / 10000);
+ final int iw = min ? d.getIntrinsicWidth() : 0;
+ w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);
}
+
int h = bounds.height();
if (mState.mScaleHeight > 0) {
- final int ih = min ? mState.mDrawable.getIntrinsicHeight() : 0;
- h -= (int) ((h - ih) * (10000 - level) * mState.mScaleHeight / 10000);
+ final int ih = min ? d.getIntrinsicHeight() : 0;
+ h -= (int) ((h - ih) * (MAX_LEVEL - level) * mState.mScaleHeight / MAX_LEVEL);
}
+
final int layoutDirection = getLayoutDirection();
Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);
if (w > 0 && h > 0) {
- mState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
- }
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mState.mDrawable.getIntrinsicWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mState.mDrawable.getIntrinsicHeight();
- }
-
- @Override
- public ConstantState getConstantState() {
- if (mState.canConstantState()) {
- mState.mChangingConfigurations = getChangingConfigurations();
- return mState;
+ d.setBounds(r.left, r.top, r.right, r.bottom);
}
- return null;
}
@Override
- public Drawable mutate() {
- if (!mMutated && super.mutate() == this) {
- mState.mDrawable.mutate();
- mMutated = true;
- }
- return this;
+ DrawableWrapperState mutateConstantState() {
+ mState = new ScaleState(mState);
+ return mState;
}
- /**
- * @hide
- */
- public void clearMutated() {
- super.clearMutated();
- mState.mDrawable.clearMutated();
- mMutated = false;
- }
-
- final static class ScaleState extends ConstantState {
+ static final class ScaleState extends DrawableWrapper.DrawableWrapperState {
/** Constant used to disable scaling for a particular dimension. */
private static final float DO_NOT_SCALE = -1.0f;
- int[] mThemeAttrs;
- int mChangingConfigurations;
-
- Drawable mDrawable;
-
float mScaleWidth = DO_NOT_SCALE;
float mScaleHeight = DO_NOT_SCALE;
int mGravity = Gravity.LEFT;
boolean mUseIntrinsicSizeAsMin = false;
- private boolean mCheckedConstantState;
- private boolean mCanConstantState;
+ ScaleState(ScaleState orig) {
+ super(orig);
- 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 {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
- }
- mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
- mDrawable.setBounds(orig.mDrawable.getBounds());
- mDrawable.setLevel(orig.mDrawable.getLevel());
mScaleWidth = orig.mScaleWidth;
mScaleHeight = orig.mScaleHeight;
mGravity = orig.mGravity;
mUseIntrinsicSizeAsMin = orig.mUseIntrinsicSizeAsMin;
- mCheckedConstantState = mCanConstantState = true;
}
}
@Override
- public boolean canApplyTheme() {
- return mThemeAttrs != null || (mDrawable != null && mDrawable.canApplyTheme())
- || super.canApplyTheme();
- }
-
- @Override
- public Drawable newDrawable() {
- return new ScaleDrawable(this, null);
- }
-
- @Override
public Drawable newDrawable(Resources res) {
return new ScaleDrawable(this, res);
}
-
- @Override
- public int getChangingConfigurations() {
- return mChangingConfigurations;
- }
-
- boolean canConstantState() {
- if (!mCheckedConstantState) {
- mCanConstantState = mDrawable.getConstantState() != null;
- mCheckedConstantState = true;
- }
-
- return mCanConstantState;
- }
-
- @Override
- public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
- final ConstantState state = mDrawable.getConstantState();
- if (state != null) {
- return state.addAtlasableBitmaps(atlasList);
- }
- return 0;
- }
}
private ScaleDrawable(ScaleState state, Resources res) {
- mState = new ScaleState(state, this, res);
+ super(state, res);
+
+ mState = state;
}
}
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 59d0ba6..c83af11 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -309,16 +309,6 @@ public class StateListDrawable extends DrawableContainer {
mMutated = false;
}
- /** @hide */
- @Override
- public void setLayoutDirection(int layoutDirection) {
- super.setLayoutDirection(layoutDirection);
-
- // Let the container handle setting its own layout direction. Otherwise,
- // we're accessing potentially unused states.
- mStateListState.setLayoutDirection(layoutDirection);
- }
-
static class StateListState extends DrawableContainerState {
int[] mThemeAttrs;
int[][] mStateSets;