From 7bc6a3f023ca3e1dde91fc97b6036dee3ba538a2 Mon Sep 17 00:00:00 2001 From: ztenghui Date: Tue, 15 Jul 2014 15:12:12 -0700 Subject: Add more reverse support to AnimatedVD bug:16162242 Change-Id: Ie0b7618beeb65ebeb65db41600165837524bcee4 --- core/java/android/animation/Animator.java | 16 ++++++++ core/java/android/animation/AnimatorSet.java | 41 ++++++++++++++++++- core/java/android/animation/ValueAnimator.java | 9 +++++ .../drawable/AnimatedStateListDrawable.java | 13 ++++-- .../graphics/drawable/AnimatedVectorDrawable.java | 24 +++++++++-- .../drawable/state_animation_vector_drawable.xml | 47 ---------------------- .../drawable/state_animation_vector_drawable01.xml | 47 ++++++++++++++++++++++ .../drawable/state_animation_vector_drawable02.xml | 26 ++++++++++++ .../drawable/state_animation_vector_drawable03.xml | 26 ++++++++++++ .../dynamic/AnimatedStateVectorDrawableTest.java | 6 ++- 10 files changed, 198 insertions(+), 57 deletions(-) delete mode 100644 tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable.xml create mode 100644 tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable01.xml create mode 100644 tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable02.xml create mode 100644 tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable03.xml diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 129e52c..95f83ac 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -356,6 +356,22 @@ public abstract class Animator implements Cloneable { public void setTarget(Object target) { } + // Hide reverse() and canReverse() for now since reverse() only work for simple + // cases, like we don't support sequential, neither startDelay. + // TODO: make reverse() works for all the Animators. + /** + * @hide + */ + public boolean canReverse() { + return false; + } + + /** + * @hide + */ + public void reverse() { + } + /** *

An animation listener receives notifications from an animation. * Notifications indicate animation related events, such as the end or the diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 018a2d6..9156eeb 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -124,7 +124,7 @@ public final class AnimatorSet extends Animator { // was set on this AnimatorSet, so it should not be passed down to the children. private TimeInterpolator mInterpolator = null; - + private boolean mReversible = true; /** * Sets up this AnimatorSet to play all of the supplied animations at the same time. * This is equivalent to calling {@link #play(Animator)} with the first animator in the @@ -177,6 +177,7 @@ public final class AnimatorSet extends Animator { if (items.length == 1) { play(items[0]); } else { + mReversible = false; for (int i = 0; i < items.length - 1; ++i) { play(items[i]).before(items[i+1]); } @@ -196,6 +197,7 @@ public final class AnimatorSet extends Animator { if (items.size() == 1) { play(items.get(0)); } else { + mReversible = false; for (int i = 0; i < items.size() - 1; ++i) { play(items.get(i)).before(items.get(i+1)); } @@ -407,6 +409,9 @@ public final class AnimatorSet extends Animator { */ @Override public void setStartDelay(long startDelay) { + if (mStartDelay > 0) { + mReversible = false; + } mStartDelay = startDelay; } @@ -512,7 +517,7 @@ public final class AnimatorSet extends Animator { node.animation.setInterpolator(mInterpolator); } } - // First, sort the nodes (if necessary). This will ensure that sortedNodes + // First, sort the nodes (if necessary). This will ensure that sortedNodes // contains the animation nodes in the correct order. sortNodes(); @@ -626,6 +631,7 @@ public final class AnimatorSet extends Animator { anim.mNodeMap = new HashMap(); anim.mNodes = new ArrayList(); anim.mSortedNodes = new ArrayList(); + anim.mReversible = mReversible; // Walk through the old nodes list, cloning each node and adding it to the new nodemap. // One problem is that the old node dependencies point to nodes in the old AnimatorSet. @@ -908,6 +914,35 @@ public final class AnimatorSet extends Animator { } /** + * @hide + */ + @Override + public boolean canReverse() { + if (!mReversible) { + return false; + } + // Loop to make sure all the Nodes can reverse. + for (Node node : mNodes) { + if (!node.animation.canReverse() || node.animation.getStartDelay() > 0) { + return false; + } + } + return true; + } + + /** + * @hide + */ + @Override + public void reverse() { + if (canReverse()) { + for (Node node : mNodes) { + node.animation.reverse(); + } + } + } + + /** * Dependency holds information about the node that some other node is * dependent upon and the nature of that dependency. * @@ -1124,6 +1159,7 @@ public final class AnimatorSet extends Animator { * {@link AnimatorSet#play(Animator)} method ends. */ public Builder before(Animator anim) { + mReversible = false; Node node = mNodeMap.get(anim); if (node == null) { node = new Node(anim); @@ -1144,6 +1180,7 @@ public final class AnimatorSet extends Animator { * {@link AnimatorSet#play(Animator)} method to play. */ public Builder after(Animator anim) { + mReversible = false; Node node = mNodeMap.get(anim); if (node == null) { node = new Node(anim); diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 5338dd0..e3380a9 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -1038,6 +1038,7 @@ public class ValueAnimator extends Animator { * play backwards. This behavior is only set for the current animation; future playing * of the animation will use the default behavior of playing forward. */ + @Override public void reverse() { mPlayingBackwards = !mPlayingBackwards; if (mPlayingState == RUNNING) { @@ -1053,6 +1054,14 @@ public class ValueAnimator extends Animator { } /** + * @hide + */ + @Override + public boolean canReverse() { + return true; + } + + /** * Called internally to end an animation by removing it from the animations list. Must be * called on the UI thread. */ diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 485b38a..d5aa5f8 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -26,6 +26,7 @@ import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.util.AttributeSet; +import android.util.Log; import android.util.LongSparseLongArray; import android.util.SparseIntArray; import android.util.StateSet; @@ -62,6 +63,8 @@ import java.io.IOException; * @attr ref android.R.styleable#DrawableStates_state_pressed */ public class AnimatedStateListDrawable extends StateListDrawable { + private static final String LOGTAG = AnimatedStateListDrawable.class.getSimpleName(); + private static final String ELEMENT_TRANSITION = "transition"; private static final String ELEMENT_ITEM = "item"; @@ -302,13 +305,13 @@ public class AnimatedStateListDrawable extends StateListDrawable { @Override public boolean canReverse() { - return true; + return mAvd.canReverse(); } @Override public void start() { if (mReversed) { - mAvd.reverse(); + reverse(); } else { mAvd.start(); } @@ -316,7 +319,11 @@ public class AnimatedStateListDrawable extends StateListDrawable { @Override public void reverse() { - mAvd.reverse(); + if (canReverse()) { + mAvd.reverse(); + } else { + Log.w(LOGTAG, "Reverse() is called on a drawable can't reverse"); + } } @Override diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 071d8ba4..11c2571 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -337,15 +337,33 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { * Reverses ongoing animations or starts pending animations in reverse. *

* NOTE: Only works of all animations are ValueAnimators. + * @hide */ - void reverse() { + public void reverse() { final ArrayList animators = mAnimatedVectorState.mAnimators; final int size = animators.size(); for (int i = 0; i < size; i++) { final Animator animator = animators.get(i); - if (animator instanceof ValueAnimator) { - ((ValueAnimator) animator).reverse(); + if (animator.canReverse()) { + animator.reverse(); + } else { + Log.w(LOGTAG, "AnimatedVectorDrawable can't reverse()"); } } } + + /** + * @hide + */ + public boolean canReverse() { + final ArrayList animators = mAnimatedVectorState.mAnimators; + final int size = animators.size(); + for (int i = 0; i < size; i++) { + final Animator animator = animators.get(i); + if (!animator.canReverse()) { + return false; + } + } + return true; + } } diff --git a/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable.xml b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable.xml deleted file mode 100644 index 30fb1b8..0000000 --- a/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable01.xml b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable01.xml new file mode 100644 index 0000000..18d7755 --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable01.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable02.xml b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable02.xml new file mode 100644 index 0000000..6a67b02 --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable02.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable03.xml b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable03.xml new file mode 100644 index 0000000..65cf25b --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/state_animation_vector_drawable03.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedStateVectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedStateVectorDrawableTest.java index 0ae0136..566cc4b 100644 --- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedStateVectorDrawableTest.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedStateVectorDrawableTest.java @@ -27,7 +27,9 @@ public class AnimatedStateVectorDrawableTest extends Activity { private static final String LOGCAT = "AnimatedStateVectorDrawableTest"; protected int[] icon = { - R.drawable.state_animation_vector_drawable + R.drawable.state_animation_vector_drawable01, + R.drawable.state_animation_vector_drawable02, + R.drawable.state_animation_vector_drawable03, }; @Override @@ -37,7 +39,7 @@ public class AnimatedStateVectorDrawableTest extends Activity { ScrollView scrollView = new ScrollView(this); GridLayout container = new GridLayout(this); scrollView.addView(container); - container.setColumnCount(1); + container.setColumnCount(5); for (int i = 0; i < icon.length; i++) { CheckBox button = new CheckBox(this); -- cgit v1.1