diff options
| author | 2015-10-02 17:16:34 +0000 | |
|---|---|---|
| committer | 2015-10-02 17:16:34 +0000 | |
| commit | 7b67734fe3601e87d3d3e54cc054884e02f58937 (patch) | |
| tree | d1cc90260ffdaad9461438acede526336cfbacf3 | |
| parent | 9994a2b1af8c2ae9eed6335fe115ba02cd6d5403 (diff) | |
| parent | f57bfe2fefc87fdb1dcc27b0f4b3a11996c15da2 (diff) | |
Merge "Fix behavior change for animators without a start delay"
| -rw-r--r-- | core/java/android/animation/AnimatorSet.java | 107 | ||||
| -rw-r--r-- | core/java/android/animation/ValueAnimator.java | 16 |
2 files changed, 69 insertions, 54 deletions
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 16f825da6f31..d444638c715a 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -603,7 +603,17 @@ public final class AnimatorSet extends Animator { createDependencyGraph(); // Now that all dependencies are set up, start the animations that should be started. - start(mRootNode); + boolean setIsEmpty = false; + if (mStartDelay > 0) { + start(mRootNode); + } else if (mNodes.size() > 1) { + // No delay, but there are other animators in the set + onChildAnimatorEnded(mDelayAnim); + } else { + // Set is empty, no delay, no other animation. Skip to end in this case + setIsEmpty = true; + } + if (mListeners != null) { ArrayList<AnimatorListener> tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone(); @@ -612,18 +622,9 @@ public final class AnimatorSet extends Animator { tmpListeners.get(i).onAnimationStart(this); } } - if (mNodes.size() == 0 && mStartDelay == 0) { - // Handle unusual case where empty AnimatorSet is started - should send out - // end event immediately since the event will not be sent out at all otherwise - mStarted = false; - if (mListeners != null) { - ArrayList<AnimatorListener> tmpListeners = - (ArrayList<AnimatorListener>) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(this); - } - } + if (setIsEmpty) { + // In the case of empty AnimatorSet, we will trigger the onAnimationEnd() right away. + onChildAnimatorEnded(mDelayAnim); } } @@ -751,44 +752,7 @@ public final class AnimatorSet extends Animator { public void onAnimationEnd(Animator animation) { animation.removeListener(this); mAnimatorSet.mPlayingSet.remove(animation); - Node animNode = mAnimatorSet.mNodeMap.get(animation); - animNode.mEnded = true; - - if (!mAnimatorSet.mTerminated) { - List<Node> children = animNode.mChildNodes; - // Start children animations, if any. - int childrenSize = children == null ? 0 : children.size(); - for (int i = 0; i < childrenSize; i++) { - if (children.get(i).mLatestParent == animNode) { - mAnimatorSet.start(children.get(i)); - } - } - // Listeners are already notified of the AnimatorSet ending in cancel() or - // end(); the logic below only kicks in when animations end normally - boolean allDone = true; - // Traverse the tree and find if there's any unfinished node - int size = mAnimatorSet.mNodes.size(); - for (int i = 0; i < size; i++) { - if (!mAnimatorSet.mNodes.get(i).mEnded) { - allDone = false; - break; - } - } - if (allDone) { - // If this was the last child animation to end, then notify listeners that this - // AnimatorSet has ended - if (mAnimatorSet.mListeners != null) { - ArrayList<AnimatorListener> tmpListeners = - (ArrayList<AnimatorListener>) mAnimatorSet.mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(mAnimatorSet); - } - } - mAnimatorSet.mStarted = false; - mAnimatorSet.mPaused = false; - } - } + mAnimatorSet.onChildAnimatorEnded(animation); } // Nothing to do @@ -801,6 +765,47 @@ public final class AnimatorSet extends Animator { } + private void onChildAnimatorEnded(Animator animation) { + Node animNode = mNodeMap.get(animation); + animNode.mEnded = true; + + if (!mTerminated) { + List<Node> children = animNode.mChildNodes; + // Start children animations, if any. + int childrenSize = children == null ? 0 : children.size(); + for (int i = 0; i < childrenSize; i++) { + if (children.get(i).mLatestParent == animNode) { + start(children.get(i)); + } + } + // Listeners are already notified of the AnimatorSet ending in cancel() or + // end(); the logic below only kicks in when animations end normally + boolean allDone = true; + // Traverse the tree and find if there's any unfinished node + int size = mNodes.size(); + for (int i = 0; i < size; i++) { + if (!mNodes.get(i).mEnded) { + allDone = false; + break; + } + } + if (allDone) { + // If this was the last child animation to end, then notify listeners that this + // AnimatorSet has ended + if (mListeners != null) { + ArrayList<AnimatorListener> tmpListeners = + (ArrayList<AnimatorListener>) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationEnd(this); + } + } + mStarted = false; + mPaused = false; + } + } + } + /** * @hide */ diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 5af6504ff699..1995ef58e499 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -932,6 +932,13 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio updateScaledDuration(); // in case the scale factor has changed since creation time AnimationHandler animationHandler = AnimationHandler.getInstance(); animationHandler.addAnimationFrameCallback(this, mStartDelay); + + if (mStartDelay == 0) { + // If there's no start delay, init the animation and notify start listeners right away + // Otherwise, postpone this until the first frame after the start delay. + startAnimation(); + setCurrentFraction(mSeekFraction == -1 ? 0 : mSeekFraction); + } } @Override @@ -1075,6 +1082,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio mStartListenersCalled = false; mPlayingBackwards = false; mReversing = false; + mLastFrameTime = 0; mCurrentIteration = 0; if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(), @@ -1184,12 +1192,13 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio * @hide */ public final void doAnimationFrame(long frameTime) { - mLastFrameTime = frameTime; AnimationHandler handler = AnimationHandler.getInstance(); - if (!mRunning) { + if (mLastFrameTime == 0) { // First frame handler.addOneShotCommitCallback(this); - startAnimation(); + if (mStartDelay > 0) { + startAnimation(); + } if (mSeekFraction < 0) { mStartTime = frameTime; } else { @@ -1199,6 +1208,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio } mStartTimeCommitted = false; // allow start time to be compensated for jank } + mLastFrameTime = frameTime; if (mPaused) { if (mPauseTime < 0) { mPauseTime = frameTime; |