summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/animation/Animator.java21
-rw-r--r--core/java/android/animation/Sequencer.java18
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.