diff options
| author | Chet Haase <chet@google.com> | 2011-03-02 17:07:35 -0800 |
|---|---|---|
| committer | Chet Haase <chet@google.com> | 2011-03-02 18:37:31 -0800 |
| commit | e8e45d32fd1f67fed1b70d0fc19d2f91a76f128e (patch) | |
| tree | c8c2281fd3367a13c7ed2ae8e79e8bdbd6938e15 /core/java/android/animation | |
| parent | 37b05d7d61cb7e7313736e14ca46c1287c5d1089 (diff) | |
| download | frameworks_base-e8e45d32fd1f67fed1b70d0fc19d2f91a76f128e.zip frameworks_base-e8e45d32fd1f67fed1b70d0fc19d2f91a76f128e.tar.gz frameworks_base-e8e45d32fd1f67fed1b70d0fc19d2f91a76f128e.tar.bz2 | |
Cancel LayoutTransition animations selectively
A recent change to LayoutTransition caused new layout transitions to
cancel any previously-running animations. This was to handle situations
where a transition adding an item needed transitions removing items to
finish their job first (and vice versa). But canceling *all* running
animations from transitions caused some artifacts, like making the status
bar icons blink or fade in, depending on which one was started last.
The new approach is to cancel just the ones we care about: adding animations
cancel removing animations, and vice versa. Either one cancels 'changing'
animations, which prevents objects from being animated to the old end
locations, since the new transition will animate them to the correct new
end locations.
Change-Id: I68ac351b05365cace6639b6618422395c35c83fd
Diffstat (limited to 'core/java/android/animation')
| -rw-r--r-- | core/java/android/animation/LayoutTransition.java | 108 |
1 files changed, 85 insertions, 23 deletions
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java index 8b59554..22dd3c7 100644 --- a/core/java/android/animation/LayoutTransition.java +++ b/core/java/android/animation/LayoutTransition.java @@ -168,7 +168,9 @@ public class LayoutTransition { */ private final HashMap<View, Animator> pendingAnimations = new HashMap<View, Animator>(); private final HashMap<View, Animator> currentChangingAnimations = new HashMap<View, Animator>(); - private final HashMap<View, Animator> currentVisibilityAnimations = + private final HashMap<View, Animator> currentAppearingAnimations = + new HashMap<View, Animator>(); + private final HashMap<View, Animator> currentDisappearingAnimations = new HashMap<View, Animator>(); /** @@ -709,7 +711,8 @@ public class LayoutTransition { * @return true if any animations in the transition are running. */ public boolean isRunning() { - return (currentChangingAnimations.size() > 0 || currentVisibilityAnimations.size() > 0); + return (currentChangingAnimations.size() > 0 || currentAppearingAnimations.size() > 0 || + currentDisappearingAnimations.size() > 0); } /** @@ -721,17 +724,74 @@ public class LayoutTransition { * @hide */ public void cancel() { - HashMap<View, Animator> currentAnimCopy = - (HashMap<View, Animator>) currentChangingAnimations.clone(); - for (Animator anim : currentAnimCopy.values()) { - anim.cancel(); + if (currentChangingAnimations.size() > 0) { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentChangingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.cancel(); + } + currentChangingAnimations.clear(); + } + if (currentAppearingAnimations.size() > 0) { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentAppearingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.end(); + } + currentAppearingAnimations.clear(); } - currentChangingAnimations.clear(); - currentAnimCopy = (HashMap<View, Animator>) currentVisibilityAnimations.clone(); - for (Animator anim : currentAnimCopy.values()) { - anim.end(); + if (currentDisappearingAnimations.size() > 0) { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentDisappearingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.end(); + } + currentDisappearingAnimations.clear(); + } + } + + /** + * Cancels the specified type of 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(int transitionType) { + switch (transitionType) { + case CHANGE_APPEARING: + case CHANGE_DISAPPEARING: + if (currentChangingAnimations.size() > 0) { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentChangingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.cancel(); + } + currentChangingAnimations.clear(); + } + break; + case APPEARING: + if (currentAppearingAnimations.size() > 0) { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentAppearingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.end(); + } + currentAppearingAnimations.clear(); + } + break; + case DISAPPEARING: + if (currentDisappearingAnimations.size() > 0) { + HashMap<View, Animator> currentAnimCopy = + (HashMap<View, Animator>) currentDisappearingAnimations.clone(); + for (Animator anim : currentAnimCopy.values()) { + anim.end(); + } + currentDisappearingAnimations.clear(); + } + break; } - currentVisibilityAnimations.clear(); } /** @@ -741,7 +801,7 @@ public class LayoutTransition { * @param child The View being added to the ViewGroup. */ private void runAppearingTransition(final ViewGroup parent, final View child) { - Animator currentAnimation = currentVisibilityAnimations.get(child); + Animator currentAnimation = currentDisappearingAnimations.get(child); if (currentAnimation != null) { currentAnimation.cancel(); } @@ -764,14 +824,14 @@ public class LayoutTransition { anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator anim) { - currentVisibilityAnimations.remove(child); + currentAppearingAnimations.remove(child); for (TransitionListener listener : mListeners) { listener.endTransition(LayoutTransition.this, parent, child, APPEARING); } } }); } - currentVisibilityAnimations.put(child, anim); + currentAppearingAnimations.put(child, anim); anim.start(); } @@ -782,7 +842,7 @@ public class LayoutTransition { * @param child The View being removed from the ViewGroup. */ private void runDisappearingTransition(final ViewGroup parent, final View child) { - Animator currentAnimation = currentVisibilityAnimations.get(child); + Animator currentAnimation = currentAppearingAnimations.get(child); if (currentAnimation != null) { currentAnimation.cancel(); } @@ -802,7 +862,7 @@ public class LayoutTransition { anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator anim) { - currentVisibilityAnimations.remove(child); + currentDisappearingAnimations.remove(child); for (TransitionListener listener : mListeners) { listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING); } @@ -812,7 +872,7 @@ public class LayoutTransition { if (anim instanceof ObjectAnimator) { ((ObjectAnimator) anim).setCurrentPlayTime(0); } - currentVisibilityAnimations.put(child, anim); + currentDisappearingAnimations.put(child, anim); anim.start(); } @@ -826,9 +886,10 @@ public class LayoutTransition { * @param child The View being added to the ViewGroup. */ public void addChild(ViewGroup parent, View child) { - if (isRunning()) { - cancel(); - } + // Want disappearing animations to finish up before proceeding + cancel(DISAPPEARING); + // Also, cancel changing animations so that we start fresh ones from current locations + cancel(CHANGE_APPEARING); if (mListeners != null) { for (TransitionListener listener : mListeners) { listener.startTransition(this, parent, child, APPEARING); @@ -861,9 +922,10 @@ public class LayoutTransition { * @param child The View being removed from the ViewGroup. */ public void removeChild(ViewGroup parent, View child) { - if (isRunning()) { - cancel(); - } + // Want appearing animations to finish up before proceeding + cancel(APPEARING); + // Also, cancel changing animations so that we start fresh ones from current locations + cancel(CHANGE_DISAPPEARING); if (mListeners != null) { for (TransitionListener listener : mListeners) { listener.startTransition(this, parent, child, DISAPPEARING); |
