diff options
| -rwxr-xr-x | core/java/android/animation/Animator.java | 21 | ||||
| -rw-r--r-- | core/java/android/animation/Sequencer.java | 18 |
2 files changed, 29 insertions, 10 deletions
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 717fc0aac03e..8b7465822cb0 100755 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -394,7 +394,8 @@ public class Animator<T> extends Animatable { for (int i = 0; i < count; ++i) { Animator anim = pendingCopy.get(i); // If the animation has a startDelay, place it on the delayed list - if (anim.mStartDelay == 0) { + if (anim.mStartDelay == 0 || anim.mPlayingState == ENDED || + anim.mPlayingState == CANCELED) { anim.startAnimation(); } else { sDelayedAnims.add(anim); @@ -700,14 +701,14 @@ public class Animator<T> extends Animatable { @Override public void end() { - if (!sAnimations.contains(this) && - (Thread.currentThread() == Looper.getMainLooper().getThread())) { - // Special case if the animation has not yet started. Set the end value. - long endTime = mDuration; - if (mRepeatCount > 0) { - endTime += mRepeatCount * mDuration; + if (!sAnimations.contains(this) && !sPendingAnimations.contains(this)) { + // Special case if the animation has not yet started; get it ready for ending + mStartedDelay = false; + sPendingAnimations.add(this); + if (sAnimationHandler == null) { + sAnimationHandler = new AnimationHandler(); } - setCurrentPlayTime(endTime); + sAnimationHandler.sendEmptyMessage(ANIMATION_START); } // Just set the ENDED flag - this causes the animation to end the next time a frame // is processed. @@ -716,7 +717,8 @@ public class Animator<T> extends Animatable { @Override public boolean isRunning() { - return mPlayingState == RUNNING; + // ENDED or CANCELED indicate that it has been ended or canceled, but not processed yet + return (mPlayingState == RUNNING || mPlayingState == ENDED || mPlayingState == CANCELED); } /** @@ -862,6 +864,7 @@ public class Animator<T> extends Animatable { // Fall through to set done flag case CANCELED: done = true; + mPlayingState = STOPPED; break; } diff --git a/core/java/android/animation/Sequencer.java b/core/java/android/animation/Sequencer.java index 63ec94078dd9..8779b3d57f3e 100644 --- a/core/java/android/animation/Sequencer.java +++ b/core/java/android/animation/Sequencer.java @@ -236,6 +236,12 @@ public final class Sequencer extends Animatable { if (mSortedNodes.size() != mNodes.size()) { // hasn't been started yet - sort the nodes now, then end them sortNodes(); + for (Node node : mSortedNodes) { + if (mSequenceListener == null) { + mSequenceListener = new SequencerAnimatableListener(this); + } + node.animation.addListener(mSequenceListener); + } } if (mSortedNodes.size() > 0) { for (Node node : mSortedNodes) { @@ -486,10 +492,12 @@ public final class Sequencer extends Animatable { public void onAnimationEnd(Animatable animation) { animation.removeListener(this); mPlayingSet.remove(animation); + Node animNode = mSequencer.mNodeMap.get(animation); + animNode.done = true; ArrayList<Node> sortedNodes = mSequencer.mSortedNodes; boolean allDone = true; for (Node node : sortedNodes) { - if (node.animation.isRunning()) { + if (!node.done) { allDone = false; break; } @@ -573,6 +581,7 @@ public final class Sequencer extends Animatable { } } } + node.done = false; } } } @@ -640,6 +649,13 @@ public final class Sequencer extends Animatable { public ArrayList<Node> nodeDependents = null; /** + * Flag indicating whether the animation in this node is finished. This flag + * is used by Sequencer to check, as each animation ends, whether all child animations + * are done and it's time to send out an end event for the entire Sequencer. + */ + public boolean done = false; + + /** * Constructs the Node with the animation that it encapsulates. A Node has no * dependencies by default; dependencies are added via the addDependency() * method. |