Loading api/current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -11287,7 +11287,7 @@ package android.graphics.drawable { public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable { public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable { ctor public AnimatedStateListDrawable(); ctor public AnimatedStateListDrawable(); method public void addState(int[], android.graphics.drawable.Drawable, int); method public void addState(int[], android.graphics.drawable.Drawable, int); method public void addTransition(int, int, android.graphics.drawable.AnimationDrawable, boolean); method public void addTransition(int, int, android.graphics.drawable.Drawable, boolean); } } public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable { public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable { graphics/java/android/graphics/drawable/Animatable.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,7 @@ package android.graphics.drawable; package android.graphics.drawable; /** /** * Interface that drawables suporting animations should implement. * Interface that drawables supporting animations should implement. */ */ public interface Animatable { public interface Animatable { /** /** Loading graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +77 −45 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.TimeInterpolator; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.res.Resources; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.content.res.TypedArray; Loading Loading @@ -82,17 +84,23 @@ public class AnimatedStateListDrawable extends StateListDrawable { @Override @Override public boolean setVisible(boolean visible, boolean restart) { public boolean setVisible(boolean visible, boolean restart) { // If we're relying on an Animatable transition, the super method // will handle visibility changes. final boolean changed = super.setVisible(visible, restart); final boolean changed = super.setVisible(visible, restart); if (mAnim != null) { if (mAnim != null) { if (visible) { if (visible) { if (changed || restart) { if (restart) { // TODO: Should this support restart? mAnim.cancel(); mAnim.end(); mAnim.start(); } else if (changed && mAnim.isPaused()) { mAnim.resume(); } } } else { } else if (mAnim.isRunning()) { mAnim.end(); mAnim.pause(); } } } } return changed; return changed; } } Loading @@ -100,26 +108,33 @@ public class AnimatedStateListDrawable extends StateListDrawable { * Add a new drawable to the set of keyframes. * Add a new drawable to the set of keyframes. * * * @param stateSet An array of resource IDs to associate with the keyframe * @param stateSet An array of resource IDs to associate with the keyframe * @param drawable The drawable to show when in the specified state * @param drawable The drawable to show when in the specified state, may not be null * @param id The unique identifier for the keyframe * @param id The unique identifier for the keyframe */ */ public void addState(int[] stateSet, Drawable drawable, int id) { public void addState(@NonNull int[] stateSet, @NonNull Drawable drawable, int id) { if (drawable != null) { if (drawable == null) { throw new IllegalArgumentException("Drawable must not be null"); } mState.addStateSet(stateSet, drawable, id); mState.addStateSet(stateSet, drawable, id); onStateChange(getState()); onStateChange(getState()); } } } /** /** * Adds a new transition between keyframes. * Adds a new transition between keyframes. * * * @param fromId Unique identifier of the starting keyframe * @param fromId Unique identifier of the starting keyframe * @param toId Unique identifier of the ending keyframe * @param toId Unique identifier of the ending keyframe * @param anim An AnimationDrawable to use as a transition * @param transition An animatable drawable to use as a transition, may not be null * @param reversible Whether the transition can be reversed * @param reversible Whether the transition can be reversed */ */ public void addTransition(int fromId, int toId, AnimationDrawable anim, boolean reversible) { public void addTransition(int fromId, int toId, @NonNull Drawable transition, mState.addTransition(fromId, toId, anim, reversible); boolean reversible) { if (transition == null) { throw new IllegalArgumentException("Transition drawable must not be null"); } mState.addTransition(fromId, toId, transition, reversible); } } @Override @Override Loading @@ -131,13 +146,16 @@ public class AnimatedStateListDrawable extends StateListDrawable { protected boolean onStateChange(int[] stateSet) { protected boolean onStateChange(int[] stateSet) { final int keyframeIndex = mState.indexOfKeyframe(stateSet); final int keyframeIndex = mState.indexOfKeyframe(stateSet); if (keyframeIndex == getCurrentIndex()) { if (keyframeIndex == getCurrentIndex()) { // No transition needed. return false; return false; } } // Attempt to find a valid transition to the keyframe. if (selectTransition(keyframeIndex)) { if (selectTransition(keyframeIndex)) { return true; return true; } } // No valid transition, attempt to jump directly to the keyframe. if (selectDrawable(keyframeIndex)) { if (selectDrawable(keyframeIndex)) { return true; return true; } } Loading @@ -146,10 +164,14 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } private boolean selectTransition(int toIndex) { private boolean selectTransition(int toIndex) { if (mAnim != null) { if (toIndex == mAnimToIndex) { if (toIndex == mAnimToIndex) { // Already animating to that keyframe. // Already animating to that keyframe. return true; return true; } if (mAnim != null) { if (toIndex == mAnimToIndex) { return true; } else if (toIndex == mAnimFromIndex) { } else if (toIndex == mAnimFromIndex) { // Reverse the current animation. // Reverse the current animation. mAnim.reverse(); mAnim.reverse(); Loading @@ -159,9 +181,14 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } // Changing animation, end the current animation. // Changing animation, end the current animation. mAnim.end(); mAnim.cancel(); mAnim = null; } } // Reset state. mAnimFromIndex = -1; mAnimToIndex = -1; final AnimatedStateListState state = mState; final AnimatedStateListState state = mState; final int fromIndex = getCurrentIndex(); final int fromIndex = getCurrentIndex(); final int fromId = state.getKeyframeIdAt(fromIndex); final int fromId = state.getKeyframeIdAt(fromIndex); Loading @@ -179,42 +206,54 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } final Drawable d = getCurrent(); final Drawable d = getCurrent(); if (!(d instanceof AnimationDrawable)) { if (d instanceof AnimationDrawable) { // Transition isn't an animation. // We can support reverse() here. final boolean reversed = mState.isTransitionReversed(fromId, toId); mAnim = getAnimationDrawableAnimator((AnimationDrawable) d, reversed); mAnim.start(); } else if (d instanceof Animatable) { // Let the transition animate itself. ((Animatable) d).start(); } else { // We don't know how to animate this transition. return false; return false; } } final AnimationDrawable ad = (AnimationDrawable) d; mAnimFromIndex = fromIndex; final boolean reversed = mState.isTransitionReversed(fromId, toId); mAnimToIndex = toIndex; return true; } private ObjectAnimator getAnimationDrawableAnimator(@NonNull AnimationDrawable ad, boolean reversed) { final int frameCount = ad.getNumberOfFrames(); final int frameCount = ad.getNumberOfFrames(); final int fromFrame = reversed ? frameCount - 1 : 0; final int fromFrame = reversed ? frameCount - 1 : 0; final int toFrame = reversed ? 0 : frameCount - 1; final int toFrame = reversed ? 0 : frameCount - 1; final FrameInterpolator interp = new FrameInterpolator(ad, reversed); final FrameInterpolator interp = new FrameInterpolator(ad, reversed); final ObjectAnimator anim = ObjectAnimator.ofInt(ad, "currentIndex", fromFrame, toFrame); final ObjectAnimator anim = ObjectAnimator.ofInt(ad, "currentIndex", fromFrame, toFrame); anim.setAutoCancel(true); anim.setAutoCancel(true); anim.setDuration(interp.getTotalDuration()); anim.setDuration(interp.getTotalDuration()); anim.addListener(mAnimListener); anim.addListener(mAnimListener); anim.setInterpolator(interp); anim.setInterpolator(interp); anim.start(); mAnim = anim; return anim; mAnimFromIndex = fromIndex; mAnimToIndex = toIndex; return true; } } @Override @Override public void jumpToCurrentState() { public void jumpToCurrentState() { // If we're relying on an Animatable transition, the super method // will handle jumping it to the current state. super.jumpToCurrentState(); super.jumpToCurrentState(); if (mAnim != null) { if (mAnim != null) { mAnim.end(); mAnim.end(); mAnim = null; } } } } @Override @Override public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.AnimatedStateListDrawable); final TypedArray a = r.obtainAttributes(attrs, R.styleable.AnimatedStateListDrawable); Loading Loading @@ -260,7 +299,8 @@ public class AnimatedStateListDrawable extends StateListDrawable { onStateChange(getState()); onStateChange(getState()); } } private int parseTransition(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) private int parseTransition(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { int drawableRes = 0; int drawableRes = 0; int fromId = 0; int fromId = 0; Loading Loading @@ -304,19 +344,11 @@ public class AnimatedStateListDrawable extends StateListDrawable { dr = Drawable.createFromXmlInner(r, parser, attrs, theme); dr = Drawable.createFromXmlInner(r, parser, attrs, theme); } } final AnimationDrawable anim; return mState.addTransition(fromId, toId, dr, reversible); if (dr instanceof AnimationDrawable) { anim = (AnimationDrawable) dr; } else { throw new XmlPullParserException(parser.getPositionDescription() + ": <transition> tag requires a 'drawable' attribute or " + "child tag defining a drawable of type <animation>"); } return mState.addTransition(fromId, toId, anim, reversible); } } private int parseItem(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) private int parseItem(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { int drawableRes = 0; int drawableRes = 0; int keyframeId = 0; int keyframeId = 0; Loading Loading @@ -390,8 +422,8 @@ public class AnimatedStateListDrawable extends StateListDrawable { final LongSparseLongArray mTransitions; final LongSparseLongArray mTransitions; final SparseIntArray mStateIds; final SparseIntArray mStateIds; AnimatedStateListState(AnimatedStateListState orig, AnimatedStateListDrawable owner, AnimatedStateListState(@Nullable AnimatedStateListState orig, Resources res) { @NonNull AnimatedStateListDrawable owner, @Nullable Resources res) { super(orig, owner, res); super(orig, owner, res); if (orig != null) { if (orig != null) { Loading @@ -403,7 +435,7 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } } } int addTransition(int fromId, int toId, AnimationDrawable anim, boolean reversible) { int addTransition(int fromId, int toId, @NonNull Drawable anim, boolean reversible) { final int pos = super.addChild(anim); final int pos = super.addChild(anim); final long keyFromTo = generateTransitionKey(fromId, toId); final long keyFromTo = generateTransitionKey(fromId, toId); mTransitions.append(keyFromTo, pos); mTransitions.append(keyFromTo, pos); Loading @@ -416,13 +448,13 @@ public class AnimatedStateListDrawable extends StateListDrawable { return addChild(anim); return addChild(anim); } } int addStateSet(int[] stateSet, Drawable drawable, int id) { int addStateSet(@NonNull int[] stateSet, @NonNull Drawable drawable, int id) { final int index = super.addStateSet(stateSet, drawable); final int index = super.addStateSet(stateSet, drawable); mStateIds.put(index, id); mStateIds.put(index, id); return index; return index; } } int indexOfKeyframe(int[] stateSet) { int indexOfKeyframe(@NonNull int[] stateSet) { final int index = super.indexOfStateSet(stateSet); final int index = super.indexOfStateSet(stateSet); if (index >= 0) { if (index >= 0) { return index; return index; Loading Loading @@ -460,13 +492,13 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } } } void setConstantState(AnimatedStateListState state) { void setConstantState(@NonNull AnimatedStateListState state) { super.setConstantState(state); super.setConstantState(state); mState = state; mState = state; } } private AnimatedStateListDrawable(AnimatedStateListState state, Resources res) { private AnimatedStateListDrawable(@Nullable AnimatedStateListState state, @Nullable Resources res) { super(null); super(null); final AnimatedStateListState newState = new AnimatedStateListState(state, this, res); final AnimatedStateListState newState = new AnimatedStateListState(state, this, res); Loading tests/VectorDrawableTest/AndroidManifest.xml +9 −0 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,15 @@ <category android:name="com.android.test.dynamic.TEST" /> <category android:name="com.android.test.dynamic.TEST" /> </intent-filter> </intent-filter> </activity> </activity> <activity android:name="AnimatedStateVectorDrawableTest" android:label="AnimatedStateList and AnimatedVectorDrawable" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.dynamic.TEST" /> </intent-filter> </activity> <activity <activity android:name="VectorDrawable01" android:name="VectorDrawable01" android:label="VectorTest1" > android:label="VectorTest1" > Loading tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable.xml 0 → 100644 +47 −0 Original line number Original line Diff line number Diff line <!-- Copyright (C) 2014 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. --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/on" android:state_checked="true" android:drawable="@drawable/vector_drawable12" /> <item android:id="@+id/off" android:drawable="@drawable/vector_drawable12" /> <transition android:fromId="@+id/off" android:toId="@+id/on"> <animated-vector android:drawable="@drawable/vector_drawable12"> <target android:name="pie1" android:animation="@anim/trim_path_animation01" /> <target android:name="v" android:animation="@anim/trim_path_animation02" /> <target android:name="v" android:animation="@anim/trim_path_animation05" /> <target android:name="rotationGroup" android:animation="@anim/trim_path_animation03" /> <target android:name="rotationGroup3" android:animation="@anim/trim_path_animation03" /> <target android:name="rotationGroupBlue" android:animation="@anim/trim_path_animation03" /> <target android:name="rotationGroup" android:animation="@anim/trim_path_animation04" /> </animated-vector> </transition> </animated-selector> Loading
api/current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -11287,7 +11287,7 @@ package android.graphics.drawable { public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable { public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable { ctor public AnimatedStateListDrawable(); ctor public AnimatedStateListDrawable(); method public void addState(int[], android.graphics.drawable.Drawable, int); method public void addState(int[], android.graphics.drawable.Drawable, int); method public void addTransition(int, int, android.graphics.drawable.AnimationDrawable, boolean); method public void addTransition(int, int, android.graphics.drawable.Drawable, boolean); } } public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable { public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
graphics/java/android/graphics/drawable/Animatable.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,7 @@ package android.graphics.drawable; package android.graphics.drawable; /** /** * Interface that drawables suporting animations should implement. * Interface that drawables supporting animations should implement. */ */ public interface Animatable { public interface Animatable { /** /** Loading
graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +77 −45 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.TimeInterpolator; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.res.Resources; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.content.res.TypedArray; Loading Loading @@ -82,17 +84,23 @@ public class AnimatedStateListDrawable extends StateListDrawable { @Override @Override public boolean setVisible(boolean visible, boolean restart) { public boolean setVisible(boolean visible, boolean restart) { // If we're relying on an Animatable transition, the super method // will handle visibility changes. final boolean changed = super.setVisible(visible, restart); final boolean changed = super.setVisible(visible, restart); if (mAnim != null) { if (mAnim != null) { if (visible) { if (visible) { if (changed || restart) { if (restart) { // TODO: Should this support restart? mAnim.cancel(); mAnim.end(); mAnim.start(); } else if (changed && mAnim.isPaused()) { mAnim.resume(); } } } else { } else if (mAnim.isRunning()) { mAnim.end(); mAnim.pause(); } } } } return changed; return changed; } } Loading @@ -100,26 +108,33 @@ public class AnimatedStateListDrawable extends StateListDrawable { * Add a new drawable to the set of keyframes. * Add a new drawable to the set of keyframes. * * * @param stateSet An array of resource IDs to associate with the keyframe * @param stateSet An array of resource IDs to associate with the keyframe * @param drawable The drawable to show when in the specified state * @param drawable The drawable to show when in the specified state, may not be null * @param id The unique identifier for the keyframe * @param id The unique identifier for the keyframe */ */ public void addState(int[] stateSet, Drawable drawable, int id) { public void addState(@NonNull int[] stateSet, @NonNull Drawable drawable, int id) { if (drawable != null) { if (drawable == null) { throw new IllegalArgumentException("Drawable must not be null"); } mState.addStateSet(stateSet, drawable, id); mState.addStateSet(stateSet, drawable, id); onStateChange(getState()); onStateChange(getState()); } } } /** /** * Adds a new transition between keyframes. * Adds a new transition between keyframes. * * * @param fromId Unique identifier of the starting keyframe * @param fromId Unique identifier of the starting keyframe * @param toId Unique identifier of the ending keyframe * @param toId Unique identifier of the ending keyframe * @param anim An AnimationDrawable to use as a transition * @param transition An animatable drawable to use as a transition, may not be null * @param reversible Whether the transition can be reversed * @param reversible Whether the transition can be reversed */ */ public void addTransition(int fromId, int toId, AnimationDrawable anim, boolean reversible) { public void addTransition(int fromId, int toId, @NonNull Drawable transition, mState.addTransition(fromId, toId, anim, reversible); boolean reversible) { if (transition == null) { throw new IllegalArgumentException("Transition drawable must not be null"); } mState.addTransition(fromId, toId, transition, reversible); } } @Override @Override Loading @@ -131,13 +146,16 @@ public class AnimatedStateListDrawable extends StateListDrawable { protected boolean onStateChange(int[] stateSet) { protected boolean onStateChange(int[] stateSet) { final int keyframeIndex = mState.indexOfKeyframe(stateSet); final int keyframeIndex = mState.indexOfKeyframe(stateSet); if (keyframeIndex == getCurrentIndex()) { if (keyframeIndex == getCurrentIndex()) { // No transition needed. return false; return false; } } // Attempt to find a valid transition to the keyframe. if (selectTransition(keyframeIndex)) { if (selectTransition(keyframeIndex)) { return true; return true; } } // No valid transition, attempt to jump directly to the keyframe. if (selectDrawable(keyframeIndex)) { if (selectDrawable(keyframeIndex)) { return true; return true; } } Loading @@ -146,10 +164,14 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } private boolean selectTransition(int toIndex) { private boolean selectTransition(int toIndex) { if (mAnim != null) { if (toIndex == mAnimToIndex) { if (toIndex == mAnimToIndex) { // Already animating to that keyframe. // Already animating to that keyframe. return true; return true; } if (mAnim != null) { if (toIndex == mAnimToIndex) { return true; } else if (toIndex == mAnimFromIndex) { } else if (toIndex == mAnimFromIndex) { // Reverse the current animation. // Reverse the current animation. mAnim.reverse(); mAnim.reverse(); Loading @@ -159,9 +181,14 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } // Changing animation, end the current animation. // Changing animation, end the current animation. mAnim.end(); mAnim.cancel(); mAnim = null; } } // Reset state. mAnimFromIndex = -1; mAnimToIndex = -1; final AnimatedStateListState state = mState; final AnimatedStateListState state = mState; final int fromIndex = getCurrentIndex(); final int fromIndex = getCurrentIndex(); final int fromId = state.getKeyframeIdAt(fromIndex); final int fromId = state.getKeyframeIdAt(fromIndex); Loading @@ -179,42 +206,54 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } final Drawable d = getCurrent(); final Drawable d = getCurrent(); if (!(d instanceof AnimationDrawable)) { if (d instanceof AnimationDrawable) { // Transition isn't an animation. // We can support reverse() here. final boolean reversed = mState.isTransitionReversed(fromId, toId); mAnim = getAnimationDrawableAnimator((AnimationDrawable) d, reversed); mAnim.start(); } else if (d instanceof Animatable) { // Let the transition animate itself. ((Animatable) d).start(); } else { // We don't know how to animate this transition. return false; return false; } } final AnimationDrawable ad = (AnimationDrawable) d; mAnimFromIndex = fromIndex; final boolean reversed = mState.isTransitionReversed(fromId, toId); mAnimToIndex = toIndex; return true; } private ObjectAnimator getAnimationDrawableAnimator(@NonNull AnimationDrawable ad, boolean reversed) { final int frameCount = ad.getNumberOfFrames(); final int frameCount = ad.getNumberOfFrames(); final int fromFrame = reversed ? frameCount - 1 : 0; final int fromFrame = reversed ? frameCount - 1 : 0; final int toFrame = reversed ? 0 : frameCount - 1; final int toFrame = reversed ? 0 : frameCount - 1; final FrameInterpolator interp = new FrameInterpolator(ad, reversed); final FrameInterpolator interp = new FrameInterpolator(ad, reversed); final ObjectAnimator anim = ObjectAnimator.ofInt(ad, "currentIndex", fromFrame, toFrame); final ObjectAnimator anim = ObjectAnimator.ofInt(ad, "currentIndex", fromFrame, toFrame); anim.setAutoCancel(true); anim.setAutoCancel(true); anim.setDuration(interp.getTotalDuration()); anim.setDuration(interp.getTotalDuration()); anim.addListener(mAnimListener); anim.addListener(mAnimListener); anim.setInterpolator(interp); anim.setInterpolator(interp); anim.start(); mAnim = anim; return anim; mAnimFromIndex = fromIndex; mAnimToIndex = toIndex; return true; } } @Override @Override public void jumpToCurrentState() { public void jumpToCurrentState() { // If we're relying on an Animatable transition, the super method // will handle jumping it to the current state. super.jumpToCurrentState(); super.jumpToCurrentState(); if (mAnim != null) { if (mAnim != null) { mAnim.end(); mAnim.end(); mAnim = null; } } } } @Override @Override public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.AnimatedStateListDrawable); final TypedArray a = r.obtainAttributes(attrs, R.styleable.AnimatedStateListDrawable); Loading Loading @@ -260,7 +299,8 @@ public class AnimatedStateListDrawable extends StateListDrawable { onStateChange(getState()); onStateChange(getState()); } } private int parseTransition(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) private int parseTransition(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { int drawableRes = 0; int drawableRes = 0; int fromId = 0; int fromId = 0; Loading Loading @@ -304,19 +344,11 @@ public class AnimatedStateListDrawable extends StateListDrawable { dr = Drawable.createFromXmlInner(r, parser, attrs, theme); dr = Drawable.createFromXmlInner(r, parser, attrs, theme); } } final AnimationDrawable anim; return mState.addTransition(fromId, toId, dr, reversible); if (dr instanceof AnimationDrawable) { anim = (AnimationDrawable) dr; } else { throw new XmlPullParserException(parser.getPositionDescription() + ": <transition> tag requires a 'drawable' attribute or " + "child tag defining a drawable of type <animation>"); } return mState.addTransition(fromId, toId, anim, reversible); } } private int parseItem(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) private int parseItem(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { int drawableRes = 0; int drawableRes = 0; int keyframeId = 0; int keyframeId = 0; Loading Loading @@ -390,8 +422,8 @@ public class AnimatedStateListDrawable extends StateListDrawable { final LongSparseLongArray mTransitions; final LongSparseLongArray mTransitions; final SparseIntArray mStateIds; final SparseIntArray mStateIds; AnimatedStateListState(AnimatedStateListState orig, AnimatedStateListDrawable owner, AnimatedStateListState(@Nullable AnimatedStateListState orig, Resources res) { @NonNull AnimatedStateListDrawable owner, @Nullable Resources res) { super(orig, owner, res); super(orig, owner, res); if (orig != null) { if (orig != null) { Loading @@ -403,7 +435,7 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } } } int addTransition(int fromId, int toId, AnimationDrawable anim, boolean reversible) { int addTransition(int fromId, int toId, @NonNull Drawable anim, boolean reversible) { final int pos = super.addChild(anim); final int pos = super.addChild(anim); final long keyFromTo = generateTransitionKey(fromId, toId); final long keyFromTo = generateTransitionKey(fromId, toId); mTransitions.append(keyFromTo, pos); mTransitions.append(keyFromTo, pos); Loading @@ -416,13 +448,13 @@ public class AnimatedStateListDrawable extends StateListDrawable { return addChild(anim); return addChild(anim); } } int addStateSet(int[] stateSet, Drawable drawable, int id) { int addStateSet(@NonNull int[] stateSet, @NonNull Drawable drawable, int id) { final int index = super.addStateSet(stateSet, drawable); final int index = super.addStateSet(stateSet, drawable); mStateIds.put(index, id); mStateIds.put(index, id); return index; return index; } } int indexOfKeyframe(int[] stateSet) { int indexOfKeyframe(@NonNull int[] stateSet) { final int index = super.indexOfStateSet(stateSet); final int index = super.indexOfStateSet(stateSet); if (index >= 0) { if (index >= 0) { return index; return index; Loading Loading @@ -460,13 +492,13 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } } } void setConstantState(AnimatedStateListState state) { void setConstantState(@NonNull AnimatedStateListState state) { super.setConstantState(state); super.setConstantState(state); mState = state; mState = state; } } private AnimatedStateListDrawable(AnimatedStateListState state, Resources res) { private AnimatedStateListDrawable(@Nullable AnimatedStateListState state, @Nullable Resources res) { super(null); super(null); final AnimatedStateListState newState = new AnimatedStateListState(state, this, res); final AnimatedStateListState newState = new AnimatedStateListState(state, this, res); Loading
tests/VectorDrawableTest/AndroidManifest.xml +9 −0 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,15 @@ <category android:name="com.android.test.dynamic.TEST" /> <category android:name="com.android.test.dynamic.TEST" /> </intent-filter> </intent-filter> </activity> </activity> <activity android:name="AnimatedStateVectorDrawableTest" android:label="AnimatedStateList and AnimatedVectorDrawable" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.dynamic.TEST" /> </intent-filter> </activity> <activity <activity android:name="VectorDrawable01" android:name="VectorDrawable01" android:label="VectorTest1" > android:label="VectorTest1" > Loading
tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable.xml 0 → 100644 +47 −0 Original line number Original line Diff line number Diff line <!-- Copyright (C) 2014 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. --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/on" android:state_checked="true" android:drawable="@drawable/vector_drawable12" /> <item android:id="@+id/off" android:drawable="@drawable/vector_drawable12" /> <transition android:fromId="@+id/off" android:toId="@+id/on"> <animated-vector android:drawable="@drawable/vector_drawable12"> <target android:name="pie1" android:animation="@anim/trim_path_animation01" /> <target android:name="v" android:animation="@anim/trim_path_animation02" /> <target android:name="v" android:animation="@anim/trim_path_animation05" /> <target android:name="rotationGroup" android:animation="@anim/trim_path_animation03" /> <target android:name="rotationGroup3" android:animation="@anim/trim_path_animation03" /> <target android:name="rotationGroupBlue" android:animation="@anim/trim_path_animation03" /> <target android:name="rotationGroup" android:animation="@anim/trim_path_animation04" /> </animated-vector> </transition> </animated-selector>