Add more reverse support to AnimatedVD
bug:16162242 Change-Id: Ie0b7618beeb65ebeb65db41600165837524bcee4
This commit is contained in:
@@ -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() {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>An animation listener receives notifications from an animation.
|
||||
* Notifications indicate animation related events, such as the end or the
|
||||
|
||||
@@ -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<Animator, Node>();
|
||||
anim.mNodes = new ArrayList<Node>();
|
||||
anim.mSortedNodes = new ArrayList<Node>();
|
||||
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.
|
||||
@@ -907,6 +913,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);
|
||||
|
||||
@@ -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) {
|
||||
@@ -1052,6 +1053,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -337,15 +337,33 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
|
||||
* Reverses ongoing animations or starts pending animations in reverse.
|
||||
* <p>
|
||||
* NOTE: Only works of all animations are ValueAnimators.
|
||||
* @hide
|
||||
*/
|
||||
void reverse() {
|
||||
public void reverse() {
|
||||
final ArrayList<Animator> 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<Animator> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
android:drawable="@drawable/vector_drawable12" />
|
||||
<item android:id="@+id/off"
|
||||
android:drawable="@drawable/vector_drawable12" />
|
||||
<transition android:fromId="@+id/off" android:toId="@+id/on">
|
||||
<transition android:fromId="@+id/off" android:toId="@+id/on" android:reversible="true">
|
||||
<animated-vector android:drawable="@drawable/vector_drawable12">
|
||||
<target
|
||||
android:name="pie1"
|
||||
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
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_drawable_grouping_1" />
|
||||
<item android:id="@+id/off"
|
||||
android:drawable="@drawable/vector_drawable_grouping_1" />
|
||||
<transition android:fromId="@+id/off" android:toId="@+id/on"
|
||||
android:drawable="@drawable/animation_vector_drawable_grouping_1"
|
||||
android:reversible="true">
|
||||
</transition>
|
||||
</animated-selector>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
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_drawable_favorite" />
|
||||
<item android:id="@+id/off"
|
||||
android:drawable="@drawable/vector_drawable_favorite" />
|
||||
<transition android:fromId="@+id/off" android:toId="@+id/on"
|
||||
android:drawable="@drawable/animation_vector_drawable_favorite"
|
||||
android:reversible="true">
|
||||
</transition>
|
||||
</animated-selector>
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user