diff options
author | Chet Haase <chet@google.com> | 2011-02-09 16:47:29 -0800 |
---|---|---|
committer | Chet Haase <chet@google.com> | 2011-02-09 16:47:29 -0800 |
commit | add6577a0196258e5a48c5deefcdb12e05c935b3 (patch) | |
tree | 4f740bbb3c53586fa7ca540732c6aca5112fdf2d /core/java/android/animation | |
parent | 5ed9a80571ede30d4cb7967227bff996c9cecb9e (diff) | |
download | frameworks_base-add6577a0196258e5a48c5deefcdb12e05c935b3.zip frameworks_base-add6577a0196258e5a48c5deefcdb12e05c935b3.tar.gz frameworks_base-add6577a0196258e5a48c5deefcdb12e05c935b3.tar.bz2 |
Fix animation and layoutTransition issues.
There were some subtle timing issues in animators with ending animations that
were not completely initialized (possibly because a startDelay'd animator
was ended before the delay elapsed).
Also, LayoutTransition had bugs around running a transition on a container
while a previously-started transition was still in progress. This could result
in some minor artifacts or crash bugs, depending on the durations and delays set
on the transition animations.
Change-Id: Ic6a69601f1ce9a55db15fff6b8ed25950b354491
Diffstat (limited to 'core/java/android/animation')
-rw-r--r-- | core/java/android/animation/LayoutTransition.java | 36 | ||||
-rwxr-xr-x | core/java/android/animation/ValueAnimator.java | 15 |
2 files changed, 38 insertions, 13 deletions
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java index d3e10f3..8b59554 100644 --- a/core/java/android/animation/LayoutTransition.java +++ b/core/java/android/animation/LayoutTransition.java @@ -617,7 +617,6 @@ public class LayoutTransition { Animator prevAnimation = currentChangingAnimations.get(child); if (prevAnimation != null) { prevAnimation.cancel(); - currentChangingAnimations.remove(child); } Animator pendingAnimation = pendingAnimations.get(child); if (pendingAnimation != null) { @@ -639,7 +638,6 @@ public class LayoutTransition { }; // Remove the animation from the cache when it ends anim.addListener(new AnimatorListenerAdapter() { - private boolean canceled = false; @Override public void onAnimationStart(Animator animator) { @@ -654,17 +652,13 @@ public class LayoutTransition { @Override public void onAnimationCancel(Animator animator) { - // we remove canceled animations immediately, not here - canceled = true; child.removeOnLayoutChangeListener(listener); layoutChangeListenerMap.remove(child); } @Override public void onAnimationEnd(Animator animator) { - if (!canceled) { - currentChangingAnimations.remove(child); - } + currentChangingAnimations.remove(child); if (mListeners != null) { for (TransitionListener listener : mListeners) { listener.endTransition(LayoutTransition.this, parent, child, @@ -719,6 +713,28 @@ public class LayoutTransition { } /** + * Cancels the currently running transition. Note that we cancel() the changing animations + * but end() the visibility animations. This is because this method is currently called + * in the context of starting a new transition, so we want to move things from their mid- + * transition positions, but we want them to have their end-transition visibility. + * + * @hide + */ + public void cancel() { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentChangingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.cancel(); + } + currentChangingAnimations.clear(); + currentAnimCopy = (HashMap<View, Animator>) currentVisibilityAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.end(); + } + currentVisibilityAnimations.clear(); + } + + /** * This method runs the animation that makes an added item appear. * * @param parent The ViewGroup to which the View is being added. @@ -810,6 +826,9 @@ public class LayoutTransition { * @param child The View being added to the ViewGroup. */ public void addChild(ViewGroup parent, View child) { + if (isRunning()) { + cancel(); + } if (mListeners != null) { for (TransitionListener listener : mListeners) { listener.startTransition(this, parent, child, APPEARING); @@ -842,6 +861,9 @@ public class LayoutTransition { * @param child The View being removed from the ViewGroup. */ public void removeChild(ViewGroup parent, View child) { + if (isRunning()) { + cancel(); + } if (mListeners != null) { for (TransitionListener listener : mListeners) { listener.startTransition(this, parent, child, DISAPPEARING); diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 5705057..5a8a74a 100755 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -895,7 +895,14 @@ public class ValueAnimator extends Animator { throw new AndroidRuntimeException("Animators may only be run on Looper threads"); } mPlayingBackwards = playBackwards; + mCurrentIteration = 0; + mPlayingState = STOPPED; + mStartedDelay = false; + sPendingAnimations.get().add(this); if (mStartDelay == 0) { + // This sets the initial value of the animation, prior to actually starting it running + setCurrentPlayTime(getCurrentPlayTime()); + if (mListeners != null) { ArrayList<AnimatorListener> tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone(); @@ -904,13 +911,7 @@ public class ValueAnimator extends Animator { tmpListeners.get(i).onAnimationStart(this); } } - // This sets the initial value of the animation, prior to actually starting it running - setCurrentPlayTime(getCurrentPlayTime()); } - mCurrentIteration = 0; - mPlayingState = STOPPED; - mStartedDelay = false; - sPendingAnimations.get().add(this); AnimationHandler animationHandler = sAnimationHandler.get(); if (animationHandler == null) { animationHandler = new AnimationHandler(); @@ -947,6 +948,8 @@ public class ValueAnimator extends Animator { // Special case if the animation has not yet started; get it ready for ending mStartedDelay = false; startAnimation(); + } else if (!mInitialized) { + initAnimation(); } // The final value set on the target varies, depending on whether the animation // was supposed to repeat an odd number of times |