Loading graphics/java/android/graphics/drawable/VectorDrawable.java +147 −34 Original line number Diff line number Diff line Loading @@ -126,9 +126,13 @@ import java.util.Stack; * <dd>Defines path data using exactly same format as "d" attribute * in the SVG's path data. This is defined in the viewport space.</dd> * <dt><code>android:fillColor</code></dt> * <dd>Defines the color to fill the path (none if not present).</dd> * <dd>Specifies the color used to fill the path. May be a color or (SDK 24+ only) a color state * list. If this property is animated, any value set by the animation will override the original * value. No path fill is drawn if this property is not specified.</dd> * <dt><code>android:strokeColor</code></dt> * <dd>Defines the color to draw the path outline (none if not present).</dd> * <dd>Specifies the color used to draw the path outline. May be a color or (SDK 24+ only) a color * state list. If this property is animated, any value set by the animation will override the * original value. No path outline is drawn if this property is not specified.</dd> * <dt><code>android:strokeWidth</code></dt> * <dd>The width a path stroke.</dd> * <dt><code>android:strokeAlpha</code></dt> Loading Loading @@ -374,19 +378,24 @@ public class VectorDrawable extends Drawable { @Override public boolean isStateful() { return super.isStateful() || (mVectorState != null && mVectorState.mTint != null && mVectorState.mTint.isStateful()); return super.isStateful() || (mVectorState != null && mVectorState.isStateful()); } @Override protected boolean onStateChange(int[] stateSet) { boolean changed = false; final VectorDrawableState state = mVectorState; if (state.mVPathRenderer != null && state.mVPathRenderer.onStateChange(stateSet)) { changed = true; state.mCacheDirty = true; } if (state.mTint != null && state.mTintMode != null) { mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); invalidateSelf(); return true; changed = true; } return false; return changed; } @Override Loading Loading @@ -664,7 +673,7 @@ public class VectorDrawable extends Drawable { if (SHAPE_PATH.equals(tagName)) { final VFullPath path = new VFullPath(); path.inflate(res, attrs, theme); currentGroup.mChildren.add(path); currentGroup.addChild(path); if (path.getPathName() != null) { pathRenderer.mVGTargetsMap.put(path.getPathName(), path); } Loading @@ -673,7 +682,7 @@ public class VectorDrawable extends Drawable { } else if (SHAPE_CLIP_PATH.equals(tagName)) { final VClipPath path = new VClipPath(); path.inflate(res, attrs, theme); currentGroup.mChildren.add(path); currentGroup.addChild(path); if (path.getPathName() != null) { pathRenderer.mVGTargetsMap.put(path.getPathName(), path); } Loading @@ -681,7 +690,7 @@ public class VectorDrawable extends Drawable { } else if (SHAPE_GROUP.equals(tagName)) { VGroup newChildGroup = new VGroup(); newChildGroup.inflate(res, attrs, theme); currentGroup.mChildren.add(newChildGroup); currentGroup.addChild(newChildGroup); groupStack.push(newChildGroup); if (newChildGroup.getGroupName() != null) { pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), Loading @@ -700,7 +709,7 @@ public class VectorDrawable extends Drawable { // Print the tree out for debug. if (DBG_VECTOR_DRAWABLE) { printGroupTree(pathRenderer.mRootGroup, 0); pathRenderer.printGroupTree(); } if (noPathTag) { Loading @@ -715,24 +724,6 @@ public class VectorDrawable extends Drawable { } } private void printGroupTree(VGroup currentGroup, int level) { String indent = ""; for (int i = 0; i < level; i++) { indent += " "; } // Print the current node Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() + " rotation is " + currentGroup.mRotate); Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); // Then print all the children groups for (int i = 0; i < currentGroup.mChildren.size(); i++) { final VObject child = currentGroup.mChildren.get(i); if (child instanceof VGroup) { printGroupTree((VGroup) child, level + 1); } } } @Override public int getChangingConfigurations() { return super.getChangingConfigurations() | mVectorState.getChangingConfigurations(); Loading Loading @@ -890,6 +881,11 @@ public class VectorDrawable extends Drawable { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } public boolean isStateful() { return (mTint != null && mTint.isStateful()) || (mVPathRenderer != null && mVPathRenderer.isStateful()); } } private static class VPathRenderer { Loading Loading @@ -972,21 +968,35 @@ public class VectorDrawable extends Drawable { mRootGroup.applyTheme(t); } public boolean onStateChange(int[] stateSet) { return mRootGroup.onStateChange(stateSet); } public boolean isStateful() { return mRootGroup.isStateful(); } public void draw(Canvas canvas, int w, int h, ColorFilter filter) { final float scaleX = w / mViewportWidth; final float scaleY = h / mViewportHeight; mRootGroup.draw(canvas, mTempState, Matrix.IDENTITY_MATRIX, filter, scaleX, scaleY); } public void printGroupTree() { mRootGroup.printGroupTree(""); } } private static class VGroup implements VObject { private static final String GROUP_INDENT = " "; // mStackedMatrix is only used temporarily when drawing, it combines all // the parents' local matrices with the current one. private final Matrix mStackedMatrix = new Matrix(); ///////////////////////////////////////////////////// // Variables below need to be copied (deep copy if applicable) for mutation. final ArrayList<VObject> mChildren = new ArrayList<>(); private final ArrayList<VObject> mChildren = new ArrayList<>(); private float mRotate = 0; private float mPivotX = 0; Loading @@ -995,6 +1005,7 @@ public class VectorDrawable extends Drawable { private float mScaleY = 1; private float mTranslateX = 0; private float mTranslateY = 0; private boolean mIsStateful; // mLocalMatrix is updated based on the update of transformation information, // either parsed from the XML or by animation. Loading @@ -1011,6 +1022,7 @@ public class VectorDrawable extends Drawable { mScaleY = copy.mScaleY; mTranslateX = copy.mTranslateX; mTranslateY = copy.mTranslateY; mIsStateful = copy.mIsStateful; mThemeAttrs = copy.mThemeAttrs; mGroupName = copy.mGroupName; mChangingConfigurations = copy.mChangingConfigurations; Loading Loading @@ -1054,6 +1066,12 @@ public class VectorDrawable extends Drawable { return mLocalMatrix; } public void addChild(VObject child) { mChildren.add(child); mIsStateful |= child.isStateful(); } @Override public void draw(Canvas canvas, TempState temp, Matrix currentMatrix, ColorFilter filter, float scaleX, float scaleY) { Loading Loading @@ -1108,6 +1126,26 @@ public class VectorDrawable extends Drawable { updateLocalMatrix(); } @Override public boolean onStateChange(int[] stateSet) { boolean changed = false; final ArrayList<VObject> children = mChildren; for (int i = 0, count = children.size(); i < count; i++) { final VObject child = children.get(i); if (child.isStateful()) { changed |= child.onStateChange(stateSet); } } return changed; } @Override public boolean isStateful() { return mIsStateful; } @Override public boolean canApplyTheme() { if (mThemeAttrs != null) { Loading Loading @@ -1139,6 +1177,9 @@ public class VectorDrawable extends Drawable { final VObject child = children.get(i); if (child.canApplyTheme()) { child.applyTheme(t); // Applying a theme may have made the child stateful. mIsStateful |= child.isStateful(); } } } Loading @@ -1153,6 +1194,24 @@ public class VectorDrawable extends Drawable { mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); } public void printGroupTree(String indent) { Log.v(LOGTAG, indent + "group:" + getGroupName() + " rotation is " + mRotate); Log.v(LOGTAG, indent + "matrix:" + getLocalMatrix().toString()); final int count = mChildren.size(); if (count > 0) { indent += GROUP_INDENT; } // Then print all the children groups. for (int i = 0; i < count; i++) { final VObject child = mChildren.get(i); if (child instanceof VGroup) { ((VGroup) child).printGroupTree(indent); } } } /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ @SuppressWarnings("unused") public float getRotation() { Loading Loading @@ -1398,6 +1457,16 @@ public class VectorDrawable extends Drawable { // No-op. } @Override public boolean onStateChange(int[] stateSet) { return false; } @Override public boolean isStateful() { return false; } private void updateStateFromTypedArray(TypedArray a) { // Account for any configuration changes. mChangingConfigurations |= a.getChangingConfigurations(); Loading Loading @@ -1427,9 +1496,11 @@ public class VectorDrawable extends Drawable { // Variables below need to be copied (deep copy if applicable) for mutation. private int[] mThemeAttrs; ColorStateList mStrokeColors = null; int mStrokeColor = Color.TRANSPARENT; float mStrokeWidth = 0; ColorStateList mFillColors = null; int mFillColor = Color.TRANSPARENT; float mStrokeAlpha = 1.0f; int mFillRule; Loading @@ -1448,11 +1519,14 @@ public class VectorDrawable extends Drawable { public VFullPath(VFullPath copy) { super(copy); mThemeAttrs = copy.mThemeAttrs; mStrokeColors = copy.mStrokeColors; mStrokeColor = copy.mStrokeColor; mStrokeWidth = copy.mStrokeWidth; mStrokeAlpha = copy.mStrokeAlpha; mFillColors = copy.mFillColors; mFillColor = copy.mFillColor; mFillRule = copy.mFillRule; mFillAlpha = copy.mFillAlpha; Loading Loading @@ -1491,6 +1565,31 @@ public class VectorDrawable extends Drawable { } } @Override public boolean onStateChange(int[] stateSet) { boolean changed = false; if (mStrokeColors != null && mStrokeColors.isStateful()) { final int strokeColor = mStrokeColor; mStrokeColor = mStrokeColors.getColorForState(stateSet, strokeColor); changed |= strokeColor != mStrokeColor; } if (mFillColors != null && mFillColors.isStateful()) { final int fillColor = mFillColor; mFillColor = mFillColors.getColorForState(stateSet, fillColor); changed |= fillColor != mFillColor; } return changed; } @Override public boolean isStateful() { return mStrokeColors != null && mStrokeColors.isStateful() || mFillColors != null && mFillColors.isStateful(); } @Override public void toPath(TempState temp, Path path) { super.toPath(temp, path); Loading Loading @@ -1614,8 +1713,20 @@ public class VectorDrawable extends Drawable { mNodes = PathParser.createNodesFromPathData(pathData); } mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, mFillColor); final ColorStateList fillColors = a.getColorStateList( R.styleable.VectorDrawablePath_fillColor); if (fillColors != null) { mFillColors = fillColors; mFillColor = fillColors.getDefaultColor(); } final ColorStateList strokeColors = a.getColorStateList( R.styleable.VectorDrawablePath_strokeColor); if (strokeColors != null) { mStrokeColors = strokeColors; mStrokeColor = strokeColors.getDefaultColor(); } mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha, mFillAlpha); mStrokeLineCap = getStrokeLineCap(a.getInt( Loading @@ -1624,8 +1735,6 @@ public class VectorDrawable extends Drawable { R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); mStrokeMiterlimit = a.getFloat( R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, mStrokeColor); mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha, mStrokeAlpha); mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, Loading Loading @@ -1662,6 +1771,7 @@ public class VectorDrawable extends Drawable { @SuppressWarnings("unused") void setStrokeColor(int strokeColor) { mStrokeColors = null; mStrokeColor = strokeColor; } Loading Loading @@ -1692,6 +1802,7 @@ public class VectorDrawable extends Drawable { @SuppressWarnings("unused") void setFillColor(int fillColor) { mFillColors = null; mFillColor = fillColor; } Loading Loading @@ -1752,5 +1863,7 @@ public class VectorDrawable extends Drawable { void inflate(Resources r, AttributeSet attrs, Theme theme); boolean canApplyTheme(); void applyTheme(Theme t); boolean onStateChange(int[] state); boolean isStateful(); } } tests/VectorDrawableTest/res/drawable/vector_drawable01.xml +6 −2 Original line number Diff line number Diff line Loading @@ -20,11 +20,15 @@ android:viewportWidth="480" > <group> <path android:name="box0" android:pathData="m0,0l480,0l0,480l-480,0l0-480z" android:fillColor="@android:color/white" /> <path android:name="box1" android:pathData="m20,200l100,90l180-180l-35-35l-145,145l-60-60l-40,40z" android:fillColor="?android:attr/colorControlActivated" android:strokeColor="?android:attr/colorControlActivated" android:fillColor="?android:attr/colorControlNormal" android:strokeColor="?android:attr/colorControlNormal" android:strokeLineCap="round" android:strokeLineJoin="round" /> </group> Loading tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java +22 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ import android.graphics.drawable.VectorDrawable; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.GridLayout; @SuppressWarnings({"UnusedDeclaration"}) Loading Loading @@ -55,6 +60,23 @@ public class VectorDrawable01 extends Activity { container.setBackgroundColor(0xFF888888); final Button []bArray = new Button[icon.length]; CheckBox toggle = new CheckBox(this); toggle.setText("Toggle"); toggle.setChecked(true); toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ViewGroup vg = (ViewGroup) buttonView.getParent(); for (int i = 0, count = vg.getChildCount(); i < count; i++) { View child = vg.getChildAt(i); if (child != buttonView) { child.setEnabled(isChecked); } } } }); container.addView(toggle); for (int i = 0; i < icon.length; i++) { Button button = new Button(this); bArray[i] = button; Loading Loading
graphics/java/android/graphics/drawable/VectorDrawable.java +147 −34 Original line number Diff line number Diff line Loading @@ -126,9 +126,13 @@ import java.util.Stack; * <dd>Defines path data using exactly same format as "d" attribute * in the SVG's path data. This is defined in the viewport space.</dd> * <dt><code>android:fillColor</code></dt> * <dd>Defines the color to fill the path (none if not present).</dd> * <dd>Specifies the color used to fill the path. May be a color or (SDK 24+ only) a color state * list. If this property is animated, any value set by the animation will override the original * value. No path fill is drawn if this property is not specified.</dd> * <dt><code>android:strokeColor</code></dt> * <dd>Defines the color to draw the path outline (none if not present).</dd> * <dd>Specifies the color used to draw the path outline. May be a color or (SDK 24+ only) a color * state list. If this property is animated, any value set by the animation will override the * original value. No path outline is drawn if this property is not specified.</dd> * <dt><code>android:strokeWidth</code></dt> * <dd>The width a path stroke.</dd> * <dt><code>android:strokeAlpha</code></dt> Loading Loading @@ -374,19 +378,24 @@ public class VectorDrawable extends Drawable { @Override public boolean isStateful() { return super.isStateful() || (mVectorState != null && mVectorState.mTint != null && mVectorState.mTint.isStateful()); return super.isStateful() || (mVectorState != null && mVectorState.isStateful()); } @Override protected boolean onStateChange(int[] stateSet) { boolean changed = false; final VectorDrawableState state = mVectorState; if (state.mVPathRenderer != null && state.mVPathRenderer.onStateChange(stateSet)) { changed = true; state.mCacheDirty = true; } if (state.mTint != null && state.mTintMode != null) { mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); invalidateSelf(); return true; changed = true; } return false; return changed; } @Override Loading Loading @@ -664,7 +673,7 @@ public class VectorDrawable extends Drawable { if (SHAPE_PATH.equals(tagName)) { final VFullPath path = new VFullPath(); path.inflate(res, attrs, theme); currentGroup.mChildren.add(path); currentGroup.addChild(path); if (path.getPathName() != null) { pathRenderer.mVGTargetsMap.put(path.getPathName(), path); } Loading @@ -673,7 +682,7 @@ public class VectorDrawable extends Drawable { } else if (SHAPE_CLIP_PATH.equals(tagName)) { final VClipPath path = new VClipPath(); path.inflate(res, attrs, theme); currentGroup.mChildren.add(path); currentGroup.addChild(path); if (path.getPathName() != null) { pathRenderer.mVGTargetsMap.put(path.getPathName(), path); } Loading @@ -681,7 +690,7 @@ public class VectorDrawable extends Drawable { } else if (SHAPE_GROUP.equals(tagName)) { VGroup newChildGroup = new VGroup(); newChildGroup.inflate(res, attrs, theme); currentGroup.mChildren.add(newChildGroup); currentGroup.addChild(newChildGroup); groupStack.push(newChildGroup); if (newChildGroup.getGroupName() != null) { pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), Loading @@ -700,7 +709,7 @@ public class VectorDrawable extends Drawable { // Print the tree out for debug. if (DBG_VECTOR_DRAWABLE) { printGroupTree(pathRenderer.mRootGroup, 0); pathRenderer.printGroupTree(); } if (noPathTag) { Loading @@ -715,24 +724,6 @@ public class VectorDrawable extends Drawable { } } private void printGroupTree(VGroup currentGroup, int level) { String indent = ""; for (int i = 0; i < level; i++) { indent += " "; } // Print the current node Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() + " rotation is " + currentGroup.mRotate); Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); // Then print all the children groups for (int i = 0; i < currentGroup.mChildren.size(); i++) { final VObject child = currentGroup.mChildren.get(i); if (child instanceof VGroup) { printGroupTree((VGroup) child, level + 1); } } } @Override public int getChangingConfigurations() { return super.getChangingConfigurations() | mVectorState.getChangingConfigurations(); Loading Loading @@ -890,6 +881,11 @@ public class VectorDrawable extends Drawable { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } public boolean isStateful() { return (mTint != null && mTint.isStateful()) || (mVPathRenderer != null && mVPathRenderer.isStateful()); } } private static class VPathRenderer { Loading Loading @@ -972,21 +968,35 @@ public class VectorDrawable extends Drawable { mRootGroup.applyTheme(t); } public boolean onStateChange(int[] stateSet) { return mRootGroup.onStateChange(stateSet); } public boolean isStateful() { return mRootGroup.isStateful(); } public void draw(Canvas canvas, int w, int h, ColorFilter filter) { final float scaleX = w / mViewportWidth; final float scaleY = h / mViewportHeight; mRootGroup.draw(canvas, mTempState, Matrix.IDENTITY_MATRIX, filter, scaleX, scaleY); } public void printGroupTree() { mRootGroup.printGroupTree(""); } } private static class VGroup implements VObject { private static final String GROUP_INDENT = " "; // mStackedMatrix is only used temporarily when drawing, it combines all // the parents' local matrices with the current one. private final Matrix mStackedMatrix = new Matrix(); ///////////////////////////////////////////////////// // Variables below need to be copied (deep copy if applicable) for mutation. final ArrayList<VObject> mChildren = new ArrayList<>(); private final ArrayList<VObject> mChildren = new ArrayList<>(); private float mRotate = 0; private float mPivotX = 0; Loading @@ -995,6 +1005,7 @@ public class VectorDrawable extends Drawable { private float mScaleY = 1; private float mTranslateX = 0; private float mTranslateY = 0; private boolean mIsStateful; // mLocalMatrix is updated based on the update of transformation information, // either parsed from the XML or by animation. Loading @@ -1011,6 +1022,7 @@ public class VectorDrawable extends Drawable { mScaleY = copy.mScaleY; mTranslateX = copy.mTranslateX; mTranslateY = copy.mTranslateY; mIsStateful = copy.mIsStateful; mThemeAttrs = copy.mThemeAttrs; mGroupName = copy.mGroupName; mChangingConfigurations = copy.mChangingConfigurations; Loading Loading @@ -1054,6 +1066,12 @@ public class VectorDrawable extends Drawable { return mLocalMatrix; } public void addChild(VObject child) { mChildren.add(child); mIsStateful |= child.isStateful(); } @Override public void draw(Canvas canvas, TempState temp, Matrix currentMatrix, ColorFilter filter, float scaleX, float scaleY) { Loading Loading @@ -1108,6 +1126,26 @@ public class VectorDrawable extends Drawable { updateLocalMatrix(); } @Override public boolean onStateChange(int[] stateSet) { boolean changed = false; final ArrayList<VObject> children = mChildren; for (int i = 0, count = children.size(); i < count; i++) { final VObject child = children.get(i); if (child.isStateful()) { changed |= child.onStateChange(stateSet); } } return changed; } @Override public boolean isStateful() { return mIsStateful; } @Override public boolean canApplyTheme() { if (mThemeAttrs != null) { Loading Loading @@ -1139,6 +1177,9 @@ public class VectorDrawable extends Drawable { final VObject child = children.get(i); if (child.canApplyTheme()) { child.applyTheme(t); // Applying a theme may have made the child stateful. mIsStateful |= child.isStateful(); } } } Loading @@ -1153,6 +1194,24 @@ public class VectorDrawable extends Drawable { mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); } public void printGroupTree(String indent) { Log.v(LOGTAG, indent + "group:" + getGroupName() + " rotation is " + mRotate); Log.v(LOGTAG, indent + "matrix:" + getLocalMatrix().toString()); final int count = mChildren.size(); if (count > 0) { indent += GROUP_INDENT; } // Then print all the children groups. for (int i = 0; i < count; i++) { final VObject child = mChildren.get(i); if (child instanceof VGroup) { ((VGroup) child).printGroupTree(indent); } } } /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ @SuppressWarnings("unused") public float getRotation() { Loading Loading @@ -1398,6 +1457,16 @@ public class VectorDrawable extends Drawable { // No-op. } @Override public boolean onStateChange(int[] stateSet) { return false; } @Override public boolean isStateful() { return false; } private void updateStateFromTypedArray(TypedArray a) { // Account for any configuration changes. mChangingConfigurations |= a.getChangingConfigurations(); Loading Loading @@ -1427,9 +1496,11 @@ public class VectorDrawable extends Drawable { // Variables below need to be copied (deep copy if applicable) for mutation. private int[] mThemeAttrs; ColorStateList mStrokeColors = null; int mStrokeColor = Color.TRANSPARENT; float mStrokeWidth = 0; ColorStateList mFillColors = null; int mFillColor = Color.TRANSPARENT; float mStrokeAlpha = 1.0f; int mFillRule; Loading @@ -1448,11 +1519,14 @@ public class VectorDrawable extends Drawable { public VFullPath(VFullPath copy) { super(copy); mThemeAttrs = copy.mThemeAttrs; mStrokeColors = copy.mStrokeColors; mStrokeColor = copy.mStrokeColor; mStrokeWidth = copy.mStrokeWidth; mStrokeAlpha = copy.mStrokeAlpha; mFillColors = copy.mFillColors; mFillColor = copy.mFillColor; mFillRule = copy.mFillRule; mFillAlpha = copy.mFillAlpha; Loading Loading @@ -1491,6 +1565,31 @@ public class VectorDrawable extends Drawable { } } @Override public boolean onStateChange(int[] stateSet) { boolean changed = false; if (mStrokeColors != null && mStrokeColors.isStateful()) { final int strokeColor = mStrokeColor; mStrokeColor = mStrokeColors.getColorForState(stateSet, strokeColor); changed |= strokeColor != mStrokeColor; } if (mFillColors != null && mFillColors.isStateful()) { final int fillColor = mFillColor; mFillColor = mFillColors.getColorForState(stateSet, fillColor); changed |= fillColor != mFillColor; } return changed; } @Override public boolean isStateful() { return mStrokeColors != null && mStrokeColors.isStateful() || mFillColors != null && mFillColors.isStateful(); } @Override public void toPath(TempState temp, Path path) { super.toPath(temp, path); Loading Loading @@ -1614,8 +1713,20 @@ public class VectorDrawable extends Drawable { mNodes = PathParser.createNodesFromPathData(pathData); } mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, mFillColor); final ColorStateList fillColors = a.getColorStateList( R.styleable.VectorDrawablePath_fillColor); if (fillColors != null) { mFillColors = fillColors; mFillColor = fillColors.getDefaultColor(); } final ColorStateList strokeColors = a.getColorStateList( R.styleable.VectorDrawablePath_strokeColor); if (strokeColors != null) { mStrokeColors = strokeColors; mStrokeColor = strokeColors.getDefaultColor(); } mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha, mFillAlpha); mStrokeLineCap = getStrokeLineCap(a.getInt( Loading @@ -1624,8 +1735,6 @@ public class VectorDrawable extends Drawable { R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); mStrokeMiterlimit = a.getFloat( R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, mStrokeColor); mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha, mStrokeAlpha); mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, Loading Loading @@ -1662,6 +1771,7 @@ public class VectorDrawable extends Drawable { @SuppressWarnings("unused") void setStrokeColor(int strokeColor) { mStrokeColors = null; mStrokeColor = strokeColor; } Loading Loading @@ -1692,6 +1802,7 @@ public class VectorDrawable extends Drawable { @SuppressWarnings("unused") void setFillColor(int fillColor) { mFillColors = null; mFillColor = fillColor; } Loading Loading @@ -1752,5 +1863,7 @@ public class VectorDrawable extends Drawable { void inflate(Resources r, AttributeSet attrs, Theme theme); boolean canApplyTheme(); void applyTheme(Theme t); boolean onStateChange(int[] state); boolean isStateful(); } }
tests/VectorDrawableTest/res/drawable/vector_drawable01.xml +6 −2 Original line number Diff line number Diff line Loading @@ -20,11 +20,15 @@ android:viewportWidth="480" > <group> <path android:name="box0" android:pathData="m0,0l480,0l0,480l-480,0l0-480z" android:fillColor="@android:color/white" /> <path android:name="box1" android:pathData="m20,200l100,90l180-180l-35-35l-145,145l-60-60l-40,40z" android:fillColor="?android:attr/colorControlActivated" android:strokeColor="?android:attr/colorControlActivated" android:fillColor="?android:attr/colorControlNormal" android:strokeColor="?android:attr/colorControlNormal" android:strokeLineCap="round" android:strokeLineJoin="round" /> </group> Loading
tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java +22 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ import android.graphics.drawable.VectorDrawable; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.GridLayout; @SuppressWarnings({"UnusedDeclaration"}) Loading Loading @@ -55,6 +60,23 @@ public class VectorDrawable01 extends Activity { container.setBackgroundColor(0xFF888888); final Button []bArray = new Button[icon.length]; CheckBox toggle = new CheckBox(this); toggle.setText("Toggle"); toggle.setChecked(true); toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ViewGroup vg = (ViewGroup) buttonView.getParent(); for (int i = 0, count = vg.getChildCount(); i < count; i++) { View child = vg.getChildAt(i); if (child != buttonView) { child.setEnabled(isChecked); } } } }); container.addView(toggle); for (int i = 0; i < icon.length; i++) { Button button = new Button(this); bArray[i] = button; Loading