summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/animation/Animator.java16
-rw-r--r--core/java/android/animation/AnimatorSet.java32
-rw-r--r--core/java/android/animation/ValueAnimator.java45
3 files changed, 67 insertions, 26 deletions
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 08ad976acb06..4ebcc446e5a2 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -26,7 +26,7 @@ import java.util.ArrayList;
* This is the superclass for classes which provide basic support for animations which can be
* started, ended, and have <code>AnimatorListeners</code> added to them.
*/
-public abstract class Animator implements Cloneable, AnimationHandler.AnimationFrameCallback {
+public abstract class Animator implements Cloneable {
/**
* The value used to indicate infinite duration (e.g. when Animators repeat infinitely).
@@ -464,24 +464,14 @@ public abstract class Animator implements Cloneable, AnimationHandler.AnimationF
throw new IllegalStateException("Reverse is not supported");
}
- /**
- * @hide
- */
- @Override
- public boolean doAnimationFrame(long frameTime) {
+ // Pulse an animation frame into the animation.
+ boolean pulseAnimationFrame(long frameTime) {
// TODO: Need to find a better signal than this. There's a bug in SystemUI that's preventing
// returning !isStarted() from working.
return false;
}
/**
- * @hide
- */
- @Override
- public void commitAnimationFrame(long frameTime) {}
-
-
- /**
* Internal use only.
* This call starts the animation in regular or reverse direction without requiring them to
* register frame callbacks. The caller will be responsible for all the subsequent animation
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 8aba4055a904..4e3b7d0739a9 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -948,7 +948,8 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
for (int i = 0; i < mPlayingSet.size(); i++) {
Node node = mPlayingSet.get(i);
if (!node.mEnded) {
- node.mEnded = node.mAnimation.doAnimationFrame(getPlayTimeForNode(playTime, node));
+ node.mEnded = node.mAnimation.pulseAnimationFrame(
+ getPlayTimeForNode(playTime, node));
}
}
@@ -978,6 +979,19 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
}
/**
+ * @hide
+ */
+ @Override
+ public void commitAnimationFrame(long frameTime) {
+ // No op.
+ }
+
+ @Override
+ boolean pulseAnimationFrame(long frameTime) {
+ return doAnimationFrame(frameTime);
+ }
+
+ /**
* When playing forward, we call start() at the animation's scheduled start time, and make sure
* to pump a frame at the animation's scheduled end time.
*
@@ -993,11 +1007,10 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
if (event.mEvent == AnimationEvent.ANIMATION_END) {
mPlayingSet.add(event.mNode);
node.mAnimation.startWithoutPulsing(true);
- node.mAnimation.doAnimationFrame(0);
+ pulseFrame(node, 0);
} else if (event.mEvent == AnimationEvent.ANIMATION_DELAY_ENDED && !node.mEnded) {
// end event:
- node.mEnded =
- node.mAnimation.doAnimationFrame(getPlayTimeForNode(playTime, node));
+ pulseFrame(node, getPlayTimeForNode(playTime, node));
}
}
} else {
@@ -1007,16 +1020,21 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
if (event.mEvent == AnimationEvent.ANIMATION_START) {
mPlayingSet.add(event.mNode);
node.mAnimation.startWithoutPulsing(false);
- node.mAnimation.doAnimationFrame(0);
+ pulseFrame(node, 0);
} else if (event.mEvent == AnimationEvent.ANIMATION_END && !node.mEnded) {
// start event:
- node.mEnded =
- node.mAnimation.doAnimationFrame(getPlayTimeForNode(playTime, node));
+ pulseFrame(node, getPlayTimeForNode(playTime, node));
}
}
}
}
+ private void pulseFrame(Node node, long frameTime) {
+ if (!node.mEnded) {
+ node.mEnded = node.mAnimation.pulseAnimationFrame(frameTime);
+ }
+ }
+
private long getPlayTimeForNode(long overallPlayTime, Node node) {
return getPlayTimeForNode(overallPlayTime, node, mReversing);
}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 470523fc4252..55ac1f478e22 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -68,7 +68,7 @@ import java.util.HashMap;
* </div>
*/
@SuppressWarnings("unchecked")
-public class ValueAnimator extends Animator {
+public class ValueAnimator extends Animator implements AnimationHandler.AnimationFrameCallback {
private static final String TAG = "ValueAnimator";
private static final boolean DEBUG = false;
@@ -225,6 +225,12 @@ public class ValueAnimator extends Animator {
private boolean mSelfPulse = true;
/**
+ * Whether or not the animator has been requested to start without pulsing. This flag gets set
+ * in startWithoutPulsing(), and reset in start().
+ */
+ private boolean mSuppressSelfPulseRequested = false;
+
+ /**
* The time interpolator to be used. The elapsed fraction of the animation will be passed
* through this interpolator to calculate the interpolated fraction, which is then used to
* calculate the animated values.
@@ -997,12 +1003,12 @@ public class ValueAnimator extends Animator {
*
* @param playBackwards Whether the ValueAnimator should start playing in reverse.
*/
- private void start(boolean playBackwards, boolean selfPulse) {
+ private void start(boolean playBackwards) {
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
mReversing = playBackwards;
- mSelfPulse = selfPulse;
+ mSelfPulse = !mSuppressSelfPulseRequested;
// Special case: reversing from seek-to-0 should act as if not seeked at all.
if (playBackwards && mSeekFraction != -1 && mSeekFraction != 0) {
if (mRepeatCount == INFINITE) {
@@ -1041,12 +1047,18 @@ public class ValueAnimator extends Animator {
}
void startWithoutPulsing(boolean inReverse) {
- start(inReverse, false);
+ mSuppressSelfPulseRequested = true;
+ if (inReverse) {
+ reverse();
+ } else {
+ start();
+ }
+ mSuppressSelfPulseRequested = false;
}
@Override
public void start() {
- start(false, true);
+ start(false);
}
@Override
@@ -1150,7 +1162,7 @@ public class ValueAnimator extends Animator {
mReversing = !mReversing;
end();
} else {
- start(true, true);
+ start(true);
}
}
@@ -1364,6 +1376,11 @@ public class ValueAnimator extends Animator {
animateValue(endFraction);
}
+ @Override
+ boolean isInitialized() {
+ return mInitialized;
+ }
+
/**
* Processes a frame of the animation, adjusting the start time if needed.
*
@@ -1430,6 +1447,20 @@ public class ValueAnimator extends Animator {
return finished;
}
+ @Override
+ boolean pulseAnimationFrame(long frameTime) {
+ if (mSelfPulse) {
+ // Pulse animation frame will *always* be after calling start(). If mSelfPulse isn't
+ // set to false at this point, that means child animators did not call super's start().
+ // This can happen when the Animator is just a non-animating wrapper around a real
+ // functional animation. In this case, we can't really pulse a frame into the animation,
+ // because the animation cannot necessarily be properly initialized (i.e. no start/end
+ // values set).
+ return false;
+ }
+ return doAnimationFrame(frameTime);
+ }
+
private void addOneShotCommitCallback() {
if (!mSelfPulse) {
return;
@@ -1514,6 +1545,8 @@ public class ValueAnimator extends Animator {
anim.mFirstFrameTime = -1;
anim.mOverallFraction = 0;
anim.mCurrentFraction = 0;
+ anim.mSelfPulse = true;
+ anim.mSuppressSelfPulseRequested = false;
PropertyValuesHolder[] oldValues = mValues;
if (oldValues != null) {