diff options
12 files changed, 298 insertions, 287 deletions
diff --git a/api/current.txt b/api/current.txt index 6f565d7..d6e66ee 100644 --- a/api/current.txt +++ b/api/current.txt @@ -8972,6 +8972,7 @@ package android.content.res { public class TypedArray { method public boolean getBoolean(int, boolean); + method public int getChangingConfigurations(); method public int getColor(int, int); method public android.content.res.ColorStateList getColorStateList(int); method public float getDimension(int, float); diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index d2146ac..645f7df 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -927,6 +927,30 @@ public class TypedArray { return attrs; } + /** + * Return a mask of the configuration parameters for which the values in + * this typed array may change. + * + * @return Returns a mask of the changing configuration parameters, as + * defined by {@link android.content.pm.ActivityInfo}. + * @see android.content.pm.ActivityInfo + */ + public int getChangingConfigurations() { + int changingConfig = 0; + + final int[] data = mData; + final int N = length(); + for (int i = 0; i < N; i++) { + final int index = i * AssetManager.STYLE_NUM_ENTRIES; + final int type = data[index + AssetManager.STYLE_TYPE]; + if (type == TypedValue.TYPE_NULL) { + continue; + } + changingConfig |= data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]; + } + return changingConfig; + } + private boolean getValueAt(int index, TypedValue outValue) { final int[] data = mData; final int type = data[index+AssetManager.STYLE_TYPE]; diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index e080375..83a8ed5 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -31,7 +31,6 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; -import android.graphics.drawable.ColorDrawable.ColorState; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Shader; @@ -712,9 +711,11 @@ public class BitmapDrawable extends Drawable { final Resources r = a.getResources(); final BitmapState state = mBitmapState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. - final int[] themeAttrs = a.extractThemeAttrs(); - state.mThemeAttrs = themeAttrs; + state.mThemeAttrs = a.extractThemeAttrs(); final int srcResId = a.getResourceId(R.styleable.BitmapDrawable_src, 0); if (srcResId != 0) { diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 3716182..ca2f7a3 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -45,7 +45,6 @@ public class ColorDrawable extends Drawable { @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_") private ColorState mColorState; - private ColorStateList mTint; private PorterDuffColorFilter mTintFilter; private boolean mMutated; @@ -215,25 +214,24 @@ public class ColorDrawable extends Drawable { super.inflate(r, parser, attrs, theme); final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ColorDrawable); - inflateStateFromTypedArray(a); + updateStateFromTypedArray(a); a.recycle(); } /** - * Initializes the constant state from the values in the typed array. + * Updates the constant state from the values in the typed array. */ - private void inflateStateFromTypedArray(TypedArray a) { + private void updateStateFromTypedArray(TypedArray a) { final ColorState state = mColorState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. - final int[] themeAttrs = a.extractThemeAttrs(); - state.mThemeAttrs = themeAttrs; + state.mThemeAttrs = a.extractThemeAttrs(); - if (themeAttrs == null || themeAttrs[R.styleable.ColorDrawable_color] == 0) { - final int color = a.getColor(R.styleable.ColorDrawable_color, 0); - state.mBaseColor = color; - state.mUseColor = color; - } + state.mBaseColor = a.getColor(R.styleable.ColorDrawable_color, state.mBaseColor); + state.mUseColor = state.mBaseColor; } @Override @@ -241,34 +239,17 @@ public class ColorDrawable extends Drawable { super.applyTheme(t); final ColorState state = mColorState; - if (state == null) { - throw new RuntimeException("Can't apply theme to <color> with no constant state"); + if (state == null || state.mThemeAttrs == null) { + return; } - final int[] themeAttrs = state.mThemeAttrs; - if (themeAttrs != null) { - final TypedArray a = t.resolveAttributes(themeAttrs, R.styleable.ColorDrawable); - updateStateFromTypedArray(a); - a.recycle(); - } - } - - /** - * Updates the constant state from the values in the typed array. - */ - private void updateStateFromTypedArray(TypedArray a) { - final ColorState state = mColorState; - - if (a.hasValue(R.styleable.ColorDrawable_color)) { - final int color = a.getColor(R.styleable.ColorDrawable_color, 0); - state.mBaseColor = color; - state.mUseColor = color; - } + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ColorDrawable); + updateStateFromTypedArray(a); + a.recycle(); } @Override public ConstantState getConstantState() { - mColorState.mChangingConfigurations = getChangingConfigurations(); return mColorState; } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index c2759ec..b050a02 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -238,9 +238,9 @@ public abstract class Drawable { * may change, requiring that it be re-created. * * @param configs A mask of the changing configuration parameters, as - * defined by {@link android.content.res.Configuration}. + * defined by {@link android.content.pm.ActivityInfo}. * - * @see android.content.res.Configuration + * @see android.content.pm.ActivityInfo */ public void setChangingConfigurations(int configs) { mChangingConfigurations = configs; @@ -255,9 +255,9 @@ public abstract class Drawable { * drawables they hold. * * @return Returns a mask of the changing configuration parameters, as - * defined by {@link android.content.res.Configuration}. + * defined by {@link android.content.pm.ActivityInfo}. * - * @see android.content.res.Configuration + * @see android.content.pm.ActivityInfo */ public int getChangingConfigurations() { return mChangingConfigurations; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 0ccce93..6e9b776 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -1011,6 +1011,9 @@ public class GradientDrawable extends Drawable { private void updateStateFromTypedArray(TypedArray a) { final GradientState state = mGradientState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. state.mThemeAttrs = a.extractThemeAttrs(); @@ -1152,6 +1155,9 @@ public class GradientDrawable extends Drawable { private void updateGradientDrawablePadding(TypedArray a) { final GradientState st = mGradientState; + // Account for any configuration changes. + st.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. st.mAttrPadding = a.extractThemeAttrs(); @@ -1170,6 +1176,9 @@ public class GradientDrawable extends Drawable { private void updateDrawableCorners(TypedArray a) { final GradientState st = mGradientState; + // Account for any configuration changes. + st.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. st.mAttrCorners = a.extractThemeAttrs(); @@ -1201,6 +1210,10 @@ public class GradientDrawable extends Drawable { private void updateGradientDrawableStroke(TypedArray a) { final GradientState st = mGradientState; + // Account for any configuration changes. + st.mChangingConfigurations |= a.getChangingConfigurations(); + + // Extract the theme attributes, if any. st.mAttrStroke = a.extractThemeAttrs(); // We have an explicit stroke defined, so the default stroke width @@ -1227,7 +1240,13 @@ public class GradientDrawable extends Drawable { } private void updateGradientDrawableSolid(TypedArray a) { - mGradientState.mAttrSolid = a.extractThemeAttrs(); + final GradientState st = mGradientState; + + // Account for any configuration changes. + st.mChangingConfigurations |= a.getChangingConfigurations(); + + // Extract the theme attributes, if any. + st.mAttrSolid = a.extractThemeAttrs(); final ColorStateList colorStateList = a.getColorStateList( R.styleable.GradientDrawableSolid_color); @@ -1240,6 +1259,9 @@ public class GradientDrawable extends Drawable { throws XmlPullParserException { final GradientState st = mGradientState; + // Account for any configuration changes. + st.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. st.mAttrGradient = a.extractThemeAttrs(); @@ -1351,6 +1373,9 @@ public class GradientDrawable extends Drawable { private void updateGradientDrawableSize(TypedArray a) { final GradientState st = mGradientState; + // Account for any configuration changes. + st.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. st.mAttrSize = a.extractThemeAttrs(); diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index e91ffb1..d214a47 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -16,6 +16,8 @@ package android.graphics.drawable; +import com.android.internal.R; + import android.annotation.NonNull; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -48,9 +50,11 @@ import java.io.IOException; * @attr ref android.R.styleable#InsetDrawable_insetBottom */ public class InsetDrawable extends Drawable implements Drawable.Callback { - // Most of this is copied from ScaleDrawable. - private InsetState mInsetState; + private static final String LOG_TAG = "InsetDrawable"; + private final Rect mTmpRect = new Rect(); + + private InsetState mInsetState; private boolean mMutated; /*package*/ InsetDrawable() { @@ -79,59 +83,81 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { @Override public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException { - int type; - - TypedArray a = r.obtainAttributes(attrs, - com.android.internal.R.styleable.InsetDrawable); - - super.inflateWithAttributes(r, parser, a, - com.android.internal.R.styleable.InsetDrawable_visible); - - int drawableRes = a.getResourceId(com.android.internal.R.styleable. - InsetDrawable_drawable, 0); - - int inLeft = a.getDimensionPixelOffset(com.android.internal.R.styleable. - InsetDrawable_insetLeft, 0); - int inTop = a.getDimensionPixelOffset(com.android.internal.R.styleable. - InsetDrawable_insetTop, 0); - int inRight = a.getDimensionPixelOffset(com.android.internal.R.styleable. - InsetDrawable_insetRight, 0); - int inBottom = a.getDimensionPixelOffset(com.android.internal.R.styleable. - InsetDrawable_insetBottom, 0); - + final TypedArray a = r.obtainAttributes(attrs, R.styleable.InsetDrawable); + super.inflateWithAttributes(r, parser, a, R.styleable.InsetDrawable_visible); + updateStateFromTypedArray(a); a.recycle(); - Drawable dr; - if (drawableRes != 0) { - dr = r.getDrawable(drawableRes); - } else { + // Load inner XML elements. + if (mInsetState.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"); + + ": <inset> tag requires a 'drawable' attribute or " + + "child tag defining a drawable"); } - dr = Drawable.createFromXmlInner(r, parser, attrs, theme); + final Drawable dr = Drawable.createFromXmlInner(r, parser, attrs, theme); + mInsetState.mDrawable = dr; + dr.setCallback(this); } - if (dr == null) { - Log.w("drawable", "No drawable specified for <inset>"); + // Verify state. + if (mInsetState.mDrawable == null) { + Log.w(LOG_TAG, "No drawable specified for <inset>"); } + } + + private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { + final InsetState state = mInsetState; + + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); - mInsetState.mDrawable = dr; - mInsetState.mInsetLeft = inLeft; - mInsetState.mInsetRight = inRight; - mInsetState.mInsetTop = inTop; - mInsetState.mInsetBottom = inBottom; + // Extract the theme attributes, if any. + state.mThemeAttrs = a.extractThemeAttrs(); + final Drawable dr = a.getDrawable(R.styleable.InsetDrawable_drawable); if (dr != null) { + state.mDrawable = dr; dr.setCallback(this); } + + state.mInsetLeft = a.getDimensionPixelOffset( + R.styleable.InsetDrawable_insetLeft, state.mInsetLeft); + state.mInsetTop = a.getDimensionPixelOffset( + R.styleable.InsetDrawable_insetTop, state.mInsetTop); + state.mInsetRight = a.getDimensionPixelOffset( + R.styleable.InsetDrawable_insetRight, state.mInsetRight); + state.mInsetBottom = a.getDimensionPixelOffset( + R.styleable.InsetDrawable_insetBottom, state.mInsetBottom); + } + + @Override + public void applyTheme(Theme t) { + super.applyTheme(t); + + final InsetState state = mInsetState; + if (state == null || state.mThemeAttrs == null) { + return; + } + + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.InsetDrawable); + try { + updateStateFromTypedArray(a); + } catch (XmlPullParserException e) { + throw new RuntimeException(e); + } finally { + a.recycle(); + } } - // overrides from Drawable.Callback + @Override + public boolean canApplyTheme() { + return mInsetState != null && mInsetState.mThemeAttrs != null; + } @Override public void invalidateDrawable(Drawable who) { @@ -157,8 +183,6 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { } } - // overrides from Drawable - @Override public void draw(Canvas canvas) { mInsetState.mDrawable.draw(canvas); @@ -316,9 +340,11 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { } final static class InsetState extends ConstantState { - Drawable mDrawable; + int[] mThemeAttrs; int mChangingConfigurations; + Drawable mDrawable; + int mInsetLeft; int mInsetTop; int mInsetRight; @@ -329,6 +355,8 @@ public class InsetDrawable extends Drawable implements Drawable.Callback { InsetState(InsetState orig, InsetDrawable owner, Resources res) { if (orig != null) { + mThemeAttrs = orig.mThemeAttrs; + mChangingConfigurations = orig.mChangingConfigurations; if (res != null) { mDrawable = orig.mDrawable.getConstantState().newDrawable(res); } else { diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 8ebb6f2..0707d66 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -155,9 +155,11 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { private void updateStateFromTypedArray(TypedArray a) { final LayerState state = mLayerState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. - final int[] themeAttrs = a.extractThemeAttrs(); - state.mThemeAttrs = themeAttrs; + state.mThemeAttrs = a.extractThemeAttrs(); mOpacityOverride = a.getInt(R.styleable.LayerDrawable_opacity, mOpacityOverride); @@ -172,7 +174,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { */ private void inflateLayers(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException { - TypedArray a; + final LayerState state = mLayerState; + final int innerDepth = parser.getDepth() + 1; int type; int depth; @@ -186,28 +189,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { continue; } - a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawableItem); - - final int[] themeAttrs = a.extractThemeAttrs(); - final int left = a.getDimensionPixelOffset( - R.styleable.LayerDrawableItem_left, 0); - final int top = a.getDimensionPixelOffset( - R.styleable.LayerDrawableItem_top, 0); - final int right = a.getDimensionPixelOffset( - R.styleable.LayerDrawableItem_right, 0); - final int bottom = a.getDimensionPixelOffset( - R.styleable.LayerDrawableItem_bottom, 0); - final int drawableRes = a.getResourceId( - R.styleable.LayerDrawableItem_drawable, 0); - final int id = a.getResourceId( - R.styleable.LayerDrawableItem_id, View.NO_ID); - + final ChildDrawable layer = new ChildDrawable(); + final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawableItem); + updateLayerFromTypedArray(layer, a); a.recycle(); - final Drawable dr; - if (drawableRes != 0) { - dr = r.getDrawable(drawableRes, theme); - } else { + if (layer.mDrawable == null) { while ((type = parser.next()) == XmlPullParser.TEXT) { } if (type != XmlPullParser.START_TAG) { @@ -215,10 +202,39 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { + ": <item> tag requires a 'drawable' attribute or " + "child tag defining a drawable"); } - dr = Drawable.createFromXmlInner(r, parser, attrs, theme); + layer.mDrawable = Drawable.createFromXmlInner(r, parser, attrs, theme); } - addLayer(dr, themeAttrs, id, left, top, right, bottom); + if (layer.mDrawable != null) { + state.mChildrenChangingConfigurations |= + layer.mDrawable.getChangingConfigurations(); + layer.mDrawable.setCallback(this); + } + } + } + + private void updateLayerFromTypedArray(ChildDrawable layer, TypedArray a) { + final LayerState state = mLayerState; + + // Account for any configuration changes. + state.mChildrenChangingConfigurations |= a.getChangingConfigurations(); + + // Extract the theme attributes, if any. + layer.mThemeAttrs = a.extractThemeAttrs(); + + layer.mInsetL = a.getDimensionPixelOffset( + R.styleable.LayerDrawableItem_left, layer.mInsetL); + layer.mInsetT = a.getDimensionPixelOffset( + R.styleable.LayerDrawableItem_top, layer.mInsetT); + layer.mInsetR = a.getDimensionPixelOffset( + R.styleable.LayerDrawableItem_right, layer.mInsetR); + layer.mInsetB = a.getDimensionPixelOffset( + R.styleable.LayerDrawableItem_bottom, layer.mInsetB); + layer.mId = a.getResourceId(R.styleable.LayerDrawableItem_id, layer.mId); + + final Drawable dr = a.getDrawable(R.styleable.LayerDrawableItem_drawable); + if (dr != null) { + layer.mDrawable = dr; } } @@ -231,19 +247,23 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { return; } - final int[] themeAttrs = state.mThemeAttrs; - if (themeAttrs != null) { - final TypedArray a = t.resolveAttributes(themeAttrs, R.styleable.LayerDrawable); + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.LayerDrawable); updateStateFromTypedArray(a); a.recycle(); } - // TODO: Update layer positions from cached typed arrays. - final ChildDrawable[] array = mLayerState.mChildren; final int N = mLayerState.mNum; for (int i = 0; i < N; i++) { final ChildDrawable layer = array[i]; + if (layer.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes(layer.mThemeAttrs, + R.styleable.LayerDrawableItem); + updateLayerFromTypedArray(layer, a); + a.recycle(); + } + final Drawable d = layer.mDrawable; if (d.canApplyTheme()) { d.applyTheme(t); @@ -297,19 +317,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { return false; } - /** - * Add a new layer to this drawable. The new layer is identified by an id. - * - * @param layer The drawable to add as a layer. - * @param themeAttrs Theme attributes extracted from the layer. - * @param id The id of the new layer. - * @param left The left padding of the new layer. - * @param top The top padding of the new layer. - * @param right The right padding of the new layer. - * @param bottom The bottom padding of the new layer. - */ - void addLayer(Drawable layer, int[] themeAttrs, int id, int left, int top, int right, - int bottom) { + void addLayer(ChildDrawable layer) { final LayerState st = mLayerState; final int N = st.mChildren != null ? st.mChildren.length : 0; final int i = st.mNum; @@ -322,10 +330,25 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { st.mChildren = nu; } - mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations(); + st.mChildren[i] = layer; + st.mNum++; + st.invalidateCache(); + } + /** + * Add a new layer to this drawable. The new layer is identified by an id. + * + * @param layer The drawable to add as a layer. + * @param themeAttrs Theme attributes extracted from the layer. + * @param id The id of the new layer. + * @param left The left padding of the new layer. + * @param top The top padding of the new layer. + * @param right The right padding of the new layer. + * @param bottom The bottom padding of the new layer. + */ + ChildDrawable addLayer(Drawable layer, int[] themeAttrs, int id, int left, int top, int right, + int bottom) { final ChildDrawable childDrawable = new ChildDrawable(); - st.mChildren[i] = childDrawable; childDrawable.mId = id; childDrawable.mThemeAttrs = themeAttrs; childDrawable.mDrawable = layer; @@ -334,10 +357,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { childDrawable.mInsetT = top; childDrawable.mInsetR = right; childDrawable.mInsetB = bottom; - st.mNum++; - st.invalidateCache(); + addLayer(childDrawable); + + mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations(); layer.setCallback(this); + + return childDrawable; } /** @@ -904,7 +930,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { public Drawable mDrawable; public int[] mThemeAttrs; public int mInsetL, mInsetT, mInsetR, mInsetB; - public int mId; + public int mId = View.NO_ID; ChildDrawable() { // Default empty constructor. diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 6642bdd..24bbf7c 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -382,9 +382,11 @@ public class NinePatchDrawable extends Drawable { final Resources r = a.getResources(); final NinePatchState state = mNinePatchState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. - final int[] themeAttrs = a.extractThemeAttrs(); - state.mThemeAttrs = themeAttrs; + state.mThemeAttrs = a.extractThemeAttrs(); state.mDither = a.getBoolean(R.styleable.NinePatchDrawable_dither, state.mDither); diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index dfe14f2..87f5989 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -358,6 +358,9 @@ public class RippleDrawable extends LayerDrawable { private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { final RippleState state = mState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. state.mTouchThemeAttrs = a.extractThemeAttrs(); diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 86765dd..9802529 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -422,6 +422,9 @@ public class ShapeDrawable extends Drawable { final ShapeState state = mShapeState; final Paint paint = state.mPaint; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. state.mThemeAttrs = a.extractThemeAttrs(); diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index b37204d..150f210 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -44,7 +44,6 @@ import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Stack; /** @@ -308,6 +307,9 @@ public class VectorDrawable extends Drawable { private void updateStateFromTypedArray(TypedArray a) { final VectorDrawableState state = mVectorState; + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + // Extract the theme attributes, if any. state.mThemeAttrs = a.extractThemeAttrs(); @@ -322,8 +324,9 @@ public class VectorDrawable extends Drawable { } } - private VPathRenderer inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) - throws XmlPullParserException, IOException { + private VPathRenderer inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, + Theme theme) throws XmlPullParserException, IOException { + final VectorDrawableState state = mVectorState; final VPathRenderer pathRenderer = new VPathRenderer(); boolean noSizeTag = true; @@ -349,12 +352,15 @@ public class VectorDrawable extends Drawable { mVGTargetsMap.put(path.getPathName(), path); } noPathTag = false; + state.mChangingConfigurations |= path.mChangingConfigurations; } else if (SHAPE_SIZE.equals(tagName)) { pathRenderer.parseSize(res, attrs); noSizeTag = false; + state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; } else if (SHAPE_VIEWPORT.equals(tagName)) { pathRenderer.parseViewport(res, attrs); noViewportTag = false; + state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; } else if (SHAPE_GROUP.equals(tagName)) { VGroup newChildGroup = new VGroup(); newChildGroup.inflate(res, attrs, theme); @@ -363,6 +369,7 @@ public class VectorDrawable extends Drawable { if (newChildGroup.getGroupName() != null) { mVGTargetsMap.put(newChildGroup.getGroupName(), newChildGroup); } + state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; } } else if (eventType == XmlPullParser.END_TAG) { final String tagName = parser.getName(); @@ -483,6 +490,8 @@ public class VectorDrawable extends Drawable { private ColorFilter mColorFilter; private PathMeasure mPathMeasure; + private int mChangingConfigurations; + private float mBaseWidth = 0; private float mBaseHeight = 0; private float mViewportWidth = 0; @@ -509,6 +518,7 @@ public class VectorDrawable extends Drawable { mBaseHeight = copy.mBaseHeight; mViewportWidth = copy.mViewportHeight; mViewportHeight = copy.mViewportHeight; + mChangingConfigurations = copy.mChangingConfigurations; } public boolean canApplyTheme() { @@ -609,7 +619,8 @@ public class VectorDrawable extends Drawable { mFinalPathMatrix.set(vGroup.mStackedMatrix); mFinalPathMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f); - mFinalPathMatrix.postTranslate(w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f); + mFinalPathMatrix.postTranslate( + w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f); ArrayList<VPath> paths = vGroup.getPaths(); for (int i = 0; i < paths.size(); i++) { @@ -687,8 +698,14 @@ public class VectorDrawable extends Drawable { private void parseViewport(Resources r, AttributeSet attrs) throws XmlPullParserException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport); - mViewportWidth = a.getFloat(R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth); - mViewportHeight = a.getFloat(R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight); + + // Account for any configuration changes. + mChangingConfigurations |= a.getChangingConfigurations(); + + mViewportWidth = a.getFloat( + R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth); + mViewportHeight = a.getFloat( + R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight); if (mViewportWidth <= 0) { throw new XmlPullParserException(a.getPositionDescription() + @@ -704,6 +721,10 @@ public class VectorDrawable extends Drawable { private void parseSize(Resources r, AttributeSet attrs) throws XmlPullParserException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize); + + // Account for any configuration changes. + mChangingConfigurations |= a.getChangingConfigurations(); + mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth); mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight); @@ -739,6 +760,7 @@ public class VectorDrawable extends Drawable { // parents' local matrices with the current one. private final Matrix mStackedMatrix = new Matrix(); + private int mChangingConfigurations; private int[] mThemeAttrs; private String mGroupName = null; @@ -847,13 +869,19 @@ public class VectorDrawable extends Drawable { return mThemeAttrs != null; } - public void applyTheme(Theme t) { - if (mThemeAttrs == null) { - return; - } + public void inflate(Resources res, AttributeSet attrs, Theme theme) { + final TypedArray a = obtainAttributes(res, theme, attrs, + R.styleable.VectorDrawableGroup); + updateStateFromTypedArray(a); + a.recycle(); + } + + private void updateStateFromTypedArray(TypedArray a) { + // Account for any configuration changes. + mChangingConfigurations |= a.getChangingConfigurations(); - final TypedArray a = t.resolveAttributes( - mThemeAttrs, R.styleable.VectorDrawablePath); + // Extract the theme attributes, if any. + mThemeAttrs = a.extractThemeAttrs(); mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); @@ -863,58 +891,22 @@ public class VectorDrawable extends Drawable { mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha); - updateLocalMatrix(); - if (a.hasValue(R.styleable.VectorDrawableGroup_name)) { - mGroupName = a.getString(R.styleable.VectorDrawableGroup_name); - } - a.recycle(); - } - - public void inflate(Resources res, AttributeSet attrs, Theme theme) { - final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawableGroup); - final int[] themeAttrs = a.extractThemeAttrs(); - - mThemeAttrs = themeAttrs; - // NOTE: The set of attributes loaded here MUST match the - // set of attributes loaded in applyTheme. - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_rotation] == 0) { - mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); - } - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_pivotX] == 0) { - mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); + final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); + if (groupName != null) { + mGroupName = groupName; } - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_pivotY] == 0) { - mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_scaleX] == 0) { - mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_scaleY] == 0) { - mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_translateX] == 0) { - mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_translateY] == 0) { - mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_name] == 0) { - mGroupName = a.getString(R.styleable.VectorDrawableGroup_name); - } + updateLocalMatrix(); + } - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_alpha] == 0) { - mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha); + public void applyTheme(Theme t) { + if (mThemeAttrs == null) { + return; } - updateLocalMatrix(); + final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); + updateStateFromTypedArray(a); a.recycle(); } @@ -939,6 +931,7 @@ public class VectorDrawable extends Drawable { } private static class VPath { + private int mChangingConfigurations; private int[] mThemeAttrs; int mStrokeColor = 0; @@ -1096,113 +1089,29 @@ public class VectorDrawable extends Drawable { mTrimPathOffset = trimPathOffset; } + public boolean canApplyTheme() { + return mThemeAttrs != null; + } + public void inflate(Resources r, AttributeSet attrs, Theme theme) { final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath); - final int[] themeAttrs = a.extractThemeAttrs(); - mThemeAttrs = themeAttrs; - - // NOTE: The set of attributes loaded here MUST match the - // set of attributes loaded in applyTheme. - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_clipToPath] == 0) { - mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_name] == 0) { - mPathName = a.getString(R.styleable.VectorDrawablePath_name); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_pathData] == 0) { - mNode = PathParser.createNodesFromPathData(a.getString( - R.styleable.VectorDrawablePath_pathData)); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_fill] == 0) { - mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_fillOpacity] == 0) { - mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity); - } - - if (themeAttrs == null - || themeAttrs[R.styleable.VectorDrawablePath_strokeLineCap] == 0) { - mStrokeLineCap = getStrokeLineCap( - a.getInt(R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); - } - - if (themeAttrs == null - || themeAttrs[R.styleable.VectorDrawablePath_strokeLineJoin] == 0) { - mStrokeLineJoin = getStrokeLineJoin( - a.getInt(R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); - } - - if (themeAttrs == null - || themeAttrs[R.styleable.VectorDrawablePath_strokeMiterLimit] == 0) { - mStrokeMiterlimit = a.getFloat( - R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_stroke] == 0) { - mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor); - } - - if (themeAttrs == null - || themeAttrs[R.styleable.VectorDrawablePath_strokeOpacity] == 0) { - mStrokeOpacity = a.getFloat( - R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_strokeWidth] == 0) { - mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth); - } - - if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_trimPathEnd] == 0) { - mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd); - } - - if (themeAttrs == null - || themeAttrs[R.styleable.VectorDrawablePath_trimPathOffset] == 0) { - mTrimPathOffset = a.getFloat( - R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); - } - - if (themeAttrs == null - || themeAttrs[R.styleable.VectorDrawablePath_trimPathStart] == 0) { - mTrimPathStart = a.getFloat( - R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); - } - - updateColorAlphas(); - + updateStateFromTypedArray(a); a.recycle(); } - public boolean canApplyTheme() { - return mThemeAttrs != null; - } - - public void applyTheme(Theme t) { - if (mThemeAttrs == null) { - return; - } + private void updateStateFromTypedArray(TypedArray a) { + // Account for any configuration changes. + mChangingConfigurations |= a.getChangingConfigurations(); - final TypedArray a = t.resolveAttributes( - mThemeAttrs, R.styleable.VectorDrawablePath); + // Extract the theme attributes, if any. + mThemeAttrs = a.extractThemeAttrs(); mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip); - - if (a.hasValue(R.styleable.VectorDrawablePath_name)) { - mPathName = a.getString(R.styleable.VectorDrawablePath_name); - } - - if (a.hasValue(R.styleable.VectorDrawablePath_pathData)) { - mNode = PathParser.createNodesFromPathData(a.getString( - R.styleable.VectorDrawablePath_pathData)); - } - + mPathName = a.getString(R.styleable.VectorDrawablePath_name); + mNode = PathParser.createNodesFromPathData(a.getString( + R.styleable.VectorDrawablePath_pathData)); mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor); mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity); - mStrokeLineCap = getStrokeLineCap(a.getInt( R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); mStrokeLineJoin = getStrokeLineJoin(a.getInt( @@ -1213,7 +1122,6 @@ public class VectorDrawable extends Drawable { mStrokeOpacity = a.getFloat( R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity); mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth); - mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd); mTrimPathOffset = a.getFloat( R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); @@ -1221,6 +1129,15 @@ public class VectorDrawable extends Drawable { R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); updateColorAlphas(); + } + + public void applyTheme(Theme t) { + if (mThemeAttrs == null) { + return; + } + + final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); + updateStateFromTypedArray(a); a.recycle(); } |