1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.animation;
18 
19 import android.annotation.CallSuper;
20 import android.annotation.IntDef;
21 import android.os.Looper;
22 import android.os.Trace;
23 import android.util.AndroidRuntimeException;
24 import android.util.Log;
25 import android.view.animation.AccelerateDecelerateInterpolator;
26 import android.view.animation.AnimationUtils;
27 import android.view.animation.LinearInterpolator;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 
34 /**
35  * This class provides a simple timing engine for running animations
36  * which calculate animated values and set them on target objects.
37  *
38  * <p>There is a single timing pulse that all animations use. It runs in a
39  * custom handler to ensure that property changes happen on the UI thread.</p>
40  *
41  * <p>By default, ValueAnimator uses non-linear time interpolation, via the
42  * {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates
43  * out of an animation. This behavior can be changed by calling
44  * {@link ValueAnimator#setInterpolator(TimeInterpolator)}.</p>
45  *
46  * <p>Animators can be created from either code or resource files. Here is an example
47  * of a ValueAnimator resource file:</p>
48  *
49  * {@sample development/samples/ApiDemos/res/anim/animator.xml ValueAnimatorResources}
50  *
51  * <p>It is also possible to use a combination of {@link PropertyValuesHolder} and
52  * {@link Keyframe} resource tags to create a multi-step animation.
53  * Note that you can specify explicit fractional values (from 0 to 1) for
54  * each keyframe to determine when, in the overall duration, the animation should arrive at that
55  * value. Alternatively, you can leave the fractions off and the keyframes will be equally
56  * distributed within the total duration:</p>
57  *
58  * {@sample development/samples/ApiDemos/res/anim/value_animator_pvh_kf.xml
59  * ValueAnimatorKeyframeResources}
60  *
61  * <div class="special reference">
62  * <h3>Developer Guides</h3>
63  * <p>For more information about animating with {@code ValueAnimator}, read the
64  * <a href="{@docRoot}guide/topics/graphics/prop-animation.html#value-animator">Property
65  * Animation</a> developer guide.</p>
66  * </div>
67  */
68 @SuppressWarnings("unchecked")
69 public class ValueAnimator extends Animator implements AnimationHandler.AnimationFrameCallback {
70     private static final String TAG = "ValueAnimator";
71     private static final boolean DEBUG = false;
72 
73     /**
74      * Internal constants
75      */
76     private static float sDurationScale = 1.0f;
77 
78     /**
79      * Internal variables
80      * NOTE: This object implements the clone() method, making a deep copy of any referenced
81      * objects. As other non-trivial fields are added to this class, make sure to add logic
82      * to clone() to make deep copies of them.
83      */
84 
85     /**
86      * The first time that the animation's animateFrame() method is called. This time is used to
87      * determine elapsed time (and therefore the elapsed fraction) in subsequent calls
88      * to animateFrame().
89      *
90      * Whenever mStartTime is set, you must also update mStartTimeCommitted.
91      */
92     long mStartTime;
93 
94     /**
95      * When true, the start time has been firmly committed as a chosen reference point in
96      * time by which the progress of the animation will be evaluated.  When false, the
97      * start time may be updated when the first animation frame is committed so as
98      * to compensate for jank that may have occurred between when the start time was
99      * initialized and when the frame was actually drawn.
100      *
101      * This flag is generally set to false during the first frame of the animation
102      * when the animation playing state transitions from STOPPED to RUNNING or
103      * resumes after having been paused.  This flag is set to true when the start time
104      * is firmly committed and should not be further compensated for jank.
105      */
106     boolean mStartTimeCommitted;
107 
108     /**
109      * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
110      * to a value.
111      */
112     float mSeekFraction = -1;
113 
114     /**
115      * Set on the next frame after pause() is called, used to calculate a new startTime
116      * or delayStartTime which allows the animator to continue from the point at which
117      * it was paused. If negative, has not yet been set.
118      */
119     private long mPauseTime;
120 
121     /**
122      * Set when an animator is resumed. This triggers logic in the next frame which
123      * actually resumes the animator.
124      */
125     private boolean mResumed = false;
126 
127     // The time interpolator to be used if none is set on the animation
128     private static final TimeInterpolator sDefaultInterpolator =
129             new AccelerateDecelerateInterpolator();
130 
131     /**
132      * Flag to indicate whether this animator is playing in reverse mode, specifically
133      * by being started or interrupted by a call to reverse(). This flag is different than
134      * mPlayingBackwards, which indicates merely whether the current iteration of the
135      * animator is playing in reverse. It is used in corner cases to determine proper end
136      * behavior.
137      */
138     private boolean mReversing;
139 
140     /**
141      * Tracks the overall fraction of the animation, ranging from 0 to mRepeatCount + 1
142      */
143     private float mOverallFraction = 0f;
144 
145     /**
146      * Tracks current elapsed/eased fraction, for querying in getAnimatedFraction().
147      * This is calculated by interpolating the fraction (range: [0, 1]) in the current iteration.
148      */
149     private float mCurrentFraction = 0f;
150 
151     /**
152      * Tracks the time (in milliseconds) when the last frame arrived.
153      */
154     private long mLastFrameTime = 0;
155 
156     /**
157      * Additional playing state to indicate whether an animator has been start()'d. There is
158      * some lag between a call to start() and the first animation frame. We should still note
159      * that the animation has been started, even if it's first animation frame has not yet
160      * happened, and reflect that state in isRunning().
161      * Note that delayed animations are different: they are not started until their first
162      * animation frame, which occurs after their delay elapses.
163      */
164     private boolean mRunning = false;
165 
166     /**
167      * Additional playing state to indicate whether an animator has been start()'d, whether or
168      * not there is a nonzero startDelay.
169      */
170     private boolean mStarted = false;
171 
172     /**
173      * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
174      * complex to keep track of since we notify listeners at different times depending on
175      * startDelay and whether start() was called before end().
176      */
177     private boolean mStartListenersCalled = false;
178 
179     /**
180      * Flag that denotes whether the animation is set up and ready to go. Used to
181      * set up animation that has not yet been started.
182      */
183     boolean mInitialized = false;
184 
185     /**
186      * Flag that tracks whether animation has been requested to end.
187      */
188     private boolean mAnimationEndRequested = false;
189 
190     //
191     // Backing variables
192     //
193 
194     // How long the animation should last in ms
195     private long mDuration = 300;
196 
197     // The amount of time in ms to delay starting the animation after start() is called. Note
198     // that this start delay is unscaled. When there is a duration scale set on the animator, the
199     // scaling factor will be applied to this delay.
200     private long mStartDelay = 0;
201 
202     // The number of times the animation will repeat. The default is 0, which means the animation
203     // will play only once
204     private int mRepeatCount = 0;
205 
206     /**
207      * The type of repetition that will occur when repeatMode is nonzero. RESTART means the
208      * animation will start from the beginning on every new cycle. REVERSE means the animation
209      * will reverse directions on each iteration.
210      */
211     private int mRepeatMode = RESTART;
212 
213     /**
214      * The time interpolator to be used. The elapsed fraction of the animation will be passed
215      * through this interpolator to calculate the interpolated fraction, which is then used to
216      * calculate the animated values.
217      */
218     private TimeInterpolator mInterpolator = sDefaultInterpolator;
219 
220     /**
221      * The set of listeners to be sent events through the life of an animation.
222      */
223     ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
224 
225     /**
226      * The property/value sets being animated.
227      */
228     PropertyValuesHolder[] mValues;
229 
230     /**
231      * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
232      * by property name during calls to getAnimatedValue(String).
233      */
234     HashMap<String, PropertyValuesHolder> mValuesMap;
235 
236     /**
237      * Public constants
238      */
239 
240     /** @hide */
241     @IntDef({RESTART, REVERSE})
242     @Retention(RetentionPolicy.SOURCE)
243     public @interface RepeatMode {}
244 
245     /**
246      * When the animation reaches the end and <code>repeatCount</code> is INFINITE
247      * or a positive value, the animation restarts from the beginning.
248      */
249     public static final int RESTART = 1;
250     /**
251      * When the animation reaches the end and <code>repeatCount</code> is INFINITE
252      * or a positive value, the animation reverses direction on every iteration.
253      */
254     public static final int REVERSE = 2;
255     /**
256      * This value used used with the {@link #setRepeatCount(int)} property to repeat
257      * the animation indefinitely.
258      */
259     public static final int INFINITE = -1;
260 
261     /**
262      * @hide
263      */
setDurationScale(float durationScale)264     public static void setDurationScale(float durationScale) {
265         sDurationScale = durationScale;
266     }
267 
268     /**
269      * @hide
270      */
getDurationScale()271     public static float getDurationScale() {
272         return sDurationScale;
273     }
274 
275     /**
276      * Creates a new ValueAnimator object. This default constructor is primarily for
277      * use internally; the factory methods which take parameters are more generally
278      * useful.
279      */
ValueAnimator()280     public ValueAnimator() {
281     }
282 
283     /**
284      * Constructs and returns a ValueAnimator that animates between int values. A single
285      * value implies that that value is the one being animated to. However, this is not typically
286      * useful in a ValueAnimator object because there is no way for the object to determine the
287      * starting value for the animation (unlike ObjectAnimator, which can derive that value
288      * from the target object and property being animated). Therefore, there should typically
289      * be two or more values.
290      *
291      * @param values A set of values that the animation will animate between over time.
292      * @return A ValueAnimator object that is set up to animate between the given values.
293      */
ofInt(int... values)294     public static ValueAnimator ofInt(int... values) {
295         ValueAnimator anim = new ValueAnimator();
296         anim.setIntValues(values);
297         return anim;
298     }
299 
300     /**
301      * Constructs and returns a ValueAnimator that animates between color values. A single
302      * value implies that that value is the one being animated to. However, this is not typically
303      * useful in a ValueAnimator object because there is no way for the object to determine the
304      * starting value for the animation (unlike ObjectAnimator, which can derive that value
305      * from the target object and property being animated). Therefore, there should typically
306      * be two or more values.
307      *
308      * @param values A set of values that the animation will animate between over time.
309      * @return A ValueAnimator object that is set up to animate between the given values.
310      */
ofArgb(int... values)311     public static ValueAnimator ofArgb(int... values) {
312         ValueAnimator anim = new ValueAnimator();
313         anim.setIntValues(values);
314         anim.setEvaluator(ArgbEvaluator.getInstance());
315         return anim;
316     }
317 
318     /**
319      * Constructs and returns a ValueAnimator that animates between float values. A single
320      * value implies that that value is the one being animated to. However, this is not typically
321      * useful in a ValueAnimator object because there is no way for the object to determine the
322      * starting value for the animation (unlike ObjectAnimator, which can derive that value
323      * from the target object and property being animated). Therefore, there should typically
324      * be two or more values.
325      *
326      * @param values A set of values that the animation will animate between over time.
327      * @return A ValueAnimator object that is set up to animate between the given values.
328      */
ofFloat(float... values)329     public static ValueAnimator ofFloat(float... values) {
330         ValueAnimator anim = new ValueAnimator();
331         anim.setFloatValues(values);
332         return anim;
333     }
334 
335     /**
336      * Constructs and returns a ValueAnimator that animates between the values
337      * specified in the PropertyValuesHolder objects.
338      *
339      * @param values A set of PropertyValuesHolder objects whose values will be animated
340      * between over time.
341      * @return A ValueAnimator object that is set up to animate between the given values.
342      */
ofPropertyValuesHolder(PropertyValuesHolder... values)343     public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
344         ValueAnimator anim = new ValueAnimator();
345         anim.setValues(values);
346         return anim;
347     }
348     /**
349      * Constructs and returns a ValueAnimator that animates between Object values. A single
350      * value implies that that value is the one being animated to. However, this is not typically
351      * useful in a ValueAnimator object because there is no way for the object to determine the
352      * starting value for the animation (unlike ObjectAnimator, which can derive that value
353      * from the target object and property being animated). Therefore, there should typically
354      * be two or more values.
355      *
356      * <p><strong>Note:</strong> The Object values are stored as references to the original
357      * objects, which means that changes to those objects after this method is called will
358      * affect the values on the animator. If the objects will be mutated externally after
359      * this method is called, callers should pass a copy of those objects instead.
360      *
361      * <p>Since ValueAnimator does not know how to animate between arbitrary Objects, this
362      * factory method also takes a TypeEvaluator object that the ValueAnimator will use
363      * to perform that interpolation.
364      *
365      * @param evaluator A TypeEvaluator that will be called on each animation frame to
366      * provide the ncessry interpolation between the Object values to derive the animated
367      * value.
368      * @param values A set of values that the animation will animate between over time.
369      * @return A ValueAnimator object that is set up to animate between the given values.
370      */
ofObject(TypeEvaluator evaluator, Object... values)371     public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
372         ValueAnimator anim = new ValueAnimator();
373         anim.setObjectValues(values);
374         anim.setEvaluator(evaluator);
375         return anim;
376     }
377 
378     /**
379      * Sets int values that will be animated between. A single
380      * value implies that that value is the one being animated to. However, this is not typically
381      * useful in a ValueAnimator object because there is no way for the object to determine the
382      * starting value for the animation (unlike ObjectAnimator, which can derive that value
383      * from the target object and property being animated). Therefore, there should typically
384      * be two or more values.
385      *
386      * <p>If there are already multiple sets of values defined for this ValueAnimator via more
387      * than one PropertyValuesHolder object, this method will set the values for the first
388      * of those objects.</p>
389      *
390      * @param values A set of values that the animation will animate between over time.
391      */
setIntValues(int... values)392     public void setIntValues(int... values) {
393         if (values == null || values.length == 0) {
394             return;
395         }
396         if (mValues == null || mValues.length == 0) {
397             setValues(PropertyValuesHolder.ofInt("", values));
398         } else {
399             PropertyValuesHolder valuesHolder = mValues[0];
400             valuesHolder.setIntValues(values);
401         }
402         // New property/values/target should cause re-initialization prior to starting
403         mInitialized = false;
404     }
405 
406     /**
407      * Sets float values that will be animated between. A single
408      * value implies that that value is the one being animated to. However, this is not typically
409      * useful in a ValueAnimator object because there is no way for the object to determine the
410      * starting value for the animation (unlike ObjectAnimator, which can derive that value
411      * from the target object and property being animated). Therefore, there should typically
412      * be two or more values.
413      *
414      * <p>If there are already multiple sets of values defined for this ValueAnimator via more
415      * than one PropertyValuesHolder object, this method will set the values for the first
416      * of those objects.</p>
417      *
418      * @param values A set of values that the animation will animate between over time.
419      */
setFloatValues(float... values)420     public void setFloatValues(float... values) {
421         if (values == null || values.length == 0) {
422             return;
423         }
424         if (mValues == null || mValues.length == 0) {
425             setValues(PropertyValuesHolder.ofFloat("", values));
426         } else {
427             PropertyValuesHolder valuesHolder = mValues[0];
428             valuesHolder.setFloatValues(values);
429         }
430         // New property/values/target should cause re-initialization prior to starting
431         mInitialized = false;
432     }
433 
434     /**
435      * Sets the values to animate between for this animation. A single
436      * value implies that that value is the one being animated to. However, this is not typically
437      * useful in a ValueAnimator object because there is no way for the object to determine the
438      * starting value for the animation (unlike ObjectAnimator, which can derive that value
439      * from the target object and property being animated). Therefore, there should typically
440      * be two or more values.
441      *
442      * <p><strong>Note:</strong> The Object values are stored as references to the original
443      * objects, which means that changes to those objects after this method is called will
444      * affect the values on the animator. If the objects will be mutated externally after
445      * this method is called, callers should pass a copy of those objects instead.
446      *
447      * <p>If there are already multiple sets of values defined for this ValueAnimator via more
448      * than one PropertyValuesHolder object, this method will set the values for the first
449      * of those objects.</p>
450      *
451      * <p>There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate
452      * between these value objects. ValueAnimator only knows how to interpolate between the
453      * primitive types specified in the other setValues() methods.</p>
454      *
455      * @param values The set of values to animate between.
456      */
setObjectValues(Object... values)457     public void setObjectValues(Object... values) {
458         if (values == null || values.length == 0) {
459             return;
460         }
461         if (mValues == null || mValues.length == 0) {
462             setValues(PropertyValuesHolder.ofObject("", null, values));
463         } else {
464             PropertyValuesHolder valuesHolder = mValues[0];
465             valuesHolder.setObjectValues(values);
466         }
467         // New property/values/target should cause re-initialization prior to starting
468         mInitialized = false;
469     }
470 
471     /**
472      * Sets the values, per property, being animated between. This function is called internally
473      * by the constructors of ValueAnimator that take a list of values. But a ValueAnimator can
474      * be constructed without values and this method can be called to set the values manually
475      * instead.
476      *
477      * @param values The set of values, per property, being animated between.
478      */
setValues(PropertyValuesHolder... values)479     public void setValues(PropertyValuesHolder... values) {
480         int numValues = values.length;
481         mValues = values;
482         mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
483         for (int i = 0; i < numValues; ++i) {
484             PropertyValuesHolder valuesHolder = values[i];
485             mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
486         }
487         // New property/values/target should cause re-initialization prior to starting
488         mInitialized = false;
489     }
490 
491     /**
492      * Returns the values that this ValueAnimator animates between. These values are stored in
493      * PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list
494      * of value objects instead.
495      *
496      * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the
497      * values, per property, that define the animation.
498      */
getValues()499     public PropertyValuesHolder[] getValues() {
500         return mValues;
501     }
502 
503     /**
504      * This function is called immediately before processing the first animation
505      * frame of an animation. If there is a nonzero <code>startDelay</code>, the
506      * function is called after that delay ends.
507      * It takes care of the final initialization steps for the
508      * animation.
509      *
510      *  <p>Overrides of this method should call the superclass method to ensure
511      *  that internal mechanisms for the animation are set up correctly.</p>
512      */
513     @CallSuper
initAnimation()514     void initAnimation() {
515         if (!mInitialized) {
516             int numValues = mValues.length;
517             for (int i = 0; i < numValues; ++i) {
518                 mValues[i].init();
519             }
520             mInitialized = true;
521         }
522     }
523 
524     /**
525      * Sets the length of the animation. The default duration is 300 milliseconds.
526      *
527      * @param duration The length of the animation, in milliseconds. This value cannot
528      * be negative.
529      * @return ValueAnimator The object called with setDuration(). This return
530      * value makes it easier to compose statements together that construct and then set the
531      * duration, as in <code>ValueAnimator.ofInt(0, 10).setDuration(500).start()</code>.
532      */
533     @Override
setDuration(long duration)534     public ValueAnimator setDuration(long duration) {
535         if (duration < 0) {
536             throw new IllegalArgumentException("Animators cannot have negative duration: " +
537                     duration);
538         }
539         mDuration = duration;
540         return this;
541     }
542 
getScaledDuration()543     private long getScaledDuration() {
544         return (long)(mDuration * sDurationScale);
545     }
546 
547     /**
548      * Gets the length of the animation. The default duration is 300 milliseconds.
549      *
550      * @return The length of the animation, in milliseconds.
551      */
552     @Override
getDuration()553     public long getDuration() {
554         return mDuration;
555     }
556 
557     @Override
getTotalDuration()558     public long getTotalDuration() {
559         if (mRepeatCount == INFINITE) {
560             return DURATION_INFINITE;
561         } else {
562             return mStartDelay + (mDuration * (mRepeatCount + 1));
563         }
564     }
565 
566     /**
567      * Sets the position of the animation to the specified point in time. This time should
568      * be between 0 and the total duration of the animation, including any repetition. If
569      * the animation has not yet been started, then it will not advance forward after it is
570      * set to this time; it will simply set the time to this value and perform any appropriate
571      * actions based on that time. If the animation is already running, then setCurrentPlayTime()
572      * will set the current playing time to this value and continue playing from that point.
573      *
574      * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
575      */
setCurrentPlayTime(long playTime)576     public void setCurrentPlayTime(long playTime) {
577         float fraction = mDuration > 0 ? (float) playTime / mDuration : 1;
578         setCurrentFraction(fraction);
579     }
580 
581     /**
582      * Sets the position of the animation to the specified fraction. This fraction should
583      * be between 0 and the total fraction of the animation, including any repetition. That is,
584      * a fraction of 0 will position the animation at the beginning, a value of 1 at the end,
585      * and a value of 2 at the end of a reversing animator that repeats once. If
586      * the animation has not yet been started, then it will not advance forward after it is
587      * set to this fraction; it will simply set the fraction to this value and perform any
588      * appropriate actions based on that fraction. If the animation is already running, then
589      * setCurrentFraction() will set the current fraction to this value and continue
590      * playing from that point. {@link Animator.AnimatorListener} events are not called
591      * due to changing the fraction; those events are only processed while the animation
592      * is running.
593      *
594      * @param fraction The fraction to which the animation is advanced or rewound. Values
595      * outside the range of 0 to the maximum fraction for the animator will be clamped to
596      * the correct range.
597      */
setCurrentFraction(float fraction)598     public void setCurrentFraction(float fraction) {
599         initAnimation();
600         fraction = clampFraction(fraction);
601         long seekTime = (long) (getScaledDuration() * fraction);
602         long currentTime = AnimationUtils.currentAnimationTimeMillis();
603         mStartTime = currentTime - seekTime;
604         mStartTimeCommitted = true; // do not allow start time to be compensated for jank
605         if (!isPulsingInternal()) {
606             // If the animation loop hasn't started, the startTime will be adjusted in the first
607             // frame based on seek fraction.
608             mSeekFraction = fraction;
609         }
610         mOverallFraction = fraction;
611         final float currentIterationFraction = getCurrentIterationFraction(fraction);
612         animateValue(currentIterationFraction);
613     }
614 
615     /**
616      * Calculates current iteration based on the overall fraction. The overall fraction will be
617      * in the range of [0, mRepeatCount + 1]. Both current iteration and fraction in the current
618      * iteration can be derived from it.
619      */
getCurrentIteration(float fraction)620     private int getCurrentIteration(float fraction) {
621         fraction = clampFraction(fraction);
622         // If the overall fraction is a positive integer, we consider the current iteration to be
623         // complete. In other words, the fraction for the current iteration would be 1, and the
624         // current iteration would be overall fraction - 1.
625         double iteration = Math.floor(fraction);
626         if (fraction == iteration && fraction > 0) {
627             iteration--;
628         }
629         return (int) iteration;
630     }
631 
632     /**
633      * Calculates the fraction of the current iteration, taking into account whether the animation
634      * should be played backwards. E.g. When the animation is played backwards in an iteration,
635      * the fraction for that iteration will go from 1f to 0f.
636      */
getCurrentIterationFraction(float fraction)637     private float getCurrentIterationFraction(float fraction) {
638         fraction = clampFraction(fraction);
639         int iteration = getCurrentIteration(fraction);
640         float currentFraction = fraction - iteration;
641         return shouldPlayBackward(iteration) ? 1f - currentFraction : currentFraction;
642     }
643 
644     /**
645      * Clamps fraction into the correct range: [0, mRepeatCount + 1]. If repeat count is infinite,
646      * no upper bound will be set for the fraction.
647      *
648      * @param fraction fraction to be clamped
649      * @return fraction clamped into the range of [0, mRepeatCount + 1]
650      */
clampFraction(float fraction)651     private float clampFraction(float fraction) {
652         if (fraction < 0) {
653             fraction = 0;
654         } else if (mRepeatCount != INFINITE) {
655             fraction = Math.min(fraction, mRepeatCount + 1);
656         }
657         return fraction;
658     }
659 
660     /**
661      * Calculates the direction of animation playing (i.e. forward or backward), based on 1)
662      * whether the entire animation is being reversed, 2) repeat mode applied to the current
663      * iteration.
664      */
shouldPlayBackward(int iteration)665     private boolean shouldPlayBackward(int iteration) {
666         if (iteration > 0 && mRepeatMode == REVERSE &&
667                 (iteration < (mRepeatCount + 1) || mRepeatCount == INFINITE)) {
668             // if we were seeked to some other iteration in a reversing animator,
669             // figure out the correct direction to start playing based on the iteration
670             if (mReversing) {
671                 return (iteration % 2) == 0;
672             } else {
673                 return (iteration % 2) != 0;
674             }
675         } else {
676             return mReversing;
677         }
678     }
679 
680     /**
681      * Gets the current position of the animation in time, which is equal to the current
682      * time minus the time that the animation started. An animation that is not yet started will
683      * return a value of zero, unless the animation has has its play time set via
684      * {@link #setCurrentPlayTime(long)} or {@link #setCurrentFraction(float)}, in which case
685      * it will return the time that was set.
686      *
687      * @return The current position in time of the animation.
688      */
getCurrentPlayTime()689     public long getCurrentPlayTime() {
690         if (!mInitialized || (!mStarted && mSeekFraction < 0)) {
691             return 0;
692         }
693         if (mSeekFraction >= 0) {
694             return (long) (mDuration * mSeekFraction);
695         }
696         float durationScale = sDurationScale == 0 ? 1 : sDurationScale;
697         return (long) ((AnimationUtils.currentAnimationTimeMillis() - mStartTime) / durationScale);
698     }
699 
700     /**
701      * The amount of time, in milliseconds, to delay starting the animation after
702      * {@link #start()} is called.
703      *
704      * @return the number of milliseconds to delay running the animation
705      */
706     @Override
getStartDelay()707     public long getStartDelay() {
708         return mStartDelay;
709     }
710 
711     /**
712      * The amount of time, in milliseconds, to delay starting the animation after
713      * {@link #start()} is called. Note that the start delay should always be non-negative. Any
714      * negative start delay will be clamped to 0 on N and above.
715      *
716      * @param startDelay The amount of the delay, in milliseconds
717      */
718     @Override
setStartDelay(long startDelay)719     public void setStartDelay(long startDelay) {
720         // Clamp start delay to non-negative range.
721         if (startDelay < 0) {
722             Log.w(TAG, "Start delay should always be non-negative");
723             startDelay = 0;
724         }
725         mStartDelay = startDelay;
726     }
727 
728     /**
729      * The amount of time, in milliseconds, between each frame of the animation. This is a
730      * requested time that the animation will attempt to honor, but the actual delay between
731      * frames may be different, depending on system load and capabilities. This is a static
732      * function because the same delay will be applied to all animations, since they are all
733      * run off of a single timing loop.
734      *
735      * The frame delay may be ignored when the animation system uses an external timing
736      * source, such as the display refresh rate (vsync), to govern animations.
737      *
738      * Note that this method should be called from the same thread that {@link #start()} is
739      * called in order to check the frame delay for that animation. A runtime exception will be
740      * thrown if the calling thread does not have a Looper.
741      *
742      * @return the requested time between frames, in milliseconds
743      */
getFrameDelay()744     public static long getFrameDelay() {
745         return AnimationHandler.getInstance().getFrameDelay();
746     }
747 
748     /**
749      * The amount of time, in milliseconds, between each frame of the animation. This is a
750      * requested time that the animation will attempt to honor, but the actual delay between
751      * frames may be different, depending on system load and capabilities. This is a static
752      * function because the same delay will be applied to all animations, since they are all
753      * run off of a single timing loop.
754      *
755      * The frame delay may be ignored when the animation system uses an external timing
756      * source, such as the display refresh rate (vsync), to govern animations.
757      *
758      * Note that this method should be called from the same thread that {@link #start()} is
759      * called in order to have the new frame delay take effect on that animation. A runtime
760      * exception will be thrown if the calling thread does not have a Looper.
761      *
762      * @param frameDelay the requested time between frames, in milliseconds
763      */
setFrameDelay(long frameDelay)764     public static void setFrameDelay(long frameDelay) {
765         AnimationHandler.getInstance().setFrameDelay(frameDelay);
766     }
767 
768     /**
769      * The most recent value calculated by this <code>ValueAnimator</code> when there is just one
770      * property being animated. This value is only sensible while the animation is running. The main
771      * purpose for this read-only property is to retrieve the value from the <code>ValueAnimator</code>
772      * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
773      * is called during each animation frame, immediately after the value is calculated.
774      *
775      * @return animatedValue The value most recently calculated by this <code>ValueAnimator</code> for
776      * the single property being animated. If there are several properties being animated
777      * (specified by several PropertyValuesHolder objects in the constructor), this function
778      * returns the animated value for the first of those objects.
779      */
getAnimatedValue()780     public Object getAnimatedValue() {
781         if (mValues != null && mValues.length > 0) {
782             return mValues[0].getAnimatedValue();
783         }
784         // Shouldn't get here; should always have values unless ValueAnimator was set up wrong
785         return null;
786     }
787 
788     /**
789      * The most recent value calculated by this <code>ValueAnimator</code> for <code>propertyName</code>.
790      * The main purpose for this read-only property is to retrieve the value from the
791      * <code>ValueAnimator</code> during a call to
792      * {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
793      * is called during each animation frame, immediately after the value is calculated.
794      *
795      * @return animatedValue The value most recently calculated for the named property
796      * by this <code>ValueAnimator</code>.
797      */
getAnimatedValue(String propertyName)798     public Object getAnimatedValue(String propertyName) {
799         PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
800         if (valuesHolder != null) {
801             return valuesHolder.getAnimatedValue();
802         } else {
803             // At least avoid crashing if called with bogus propertyName
804             return null;
805         }
806     }
807 
808     /**
809      * Sets how many times the animation should be repeated. If the repeat
810      * count is 0, the animation is never repeated. If the repeat count is
811      * greater than 0 or {@link #INFINITE}, the repeat mode will be taken
812      * into account. The repeat count is 0 by default.
813      *
814      * @param value the number of times the animation should be repeated
815      */
setRepeatCount(int value)816     public void setRepeatCount(int value) {
817         mRepeatCount = value;
818     }
819     /**
820      * Defines how many times the animation should repeat. The default value
821      * is 0.
822      *
823      * @return the number of times the animation should repeat, or {@link #INFINITE}
824      */
getRepeatCount()825     public int getRepeatCount() {
826         return mRepeatCount;
827     }
828 
829     /**
830      * Defines what this animation should do when it reaches the end. This
831      * setting is applied only when the repeat count is either greater than
832      * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}.
833      *
834      * @param value {@link #RESTART} or {@link #REVERSE}
835      */
setRepeatMode(@epeatMode int value)836     public void setRepeatMode(@RepeatMode int value) {
837         mRepeatMode = value;
838     }
839 
840     /**
841      * Defines what this animation should do when it reaches the end.
842      *
843      * @return either one of {@link #REVERSE} or {@link #RESTART}
844      */
845     @RepeatMode
getRepeatMode()846     public int getRepeatMode() {
847         return mRepeatMode;
848     }
849 
850     /**
851      * Adds a listener to the set of listeners that are sent update events through the life of
852      * an animation. This method is called on all listeners for every frame of the animation,
853      * after the values for the animation have been calculated.
854      *
855      * @param listener the listener to be added to the current set of listeners for this animation.
856      */
addUpdateListener(AnimatorUpdateListener listener)857     public void addUpdateListener(AnimatorUpdateListener listener) {
858         if (mUpdateListeners == null) {
859             mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
860         }
861         mUpdateListeners.add(listener);
862     }
863 
864     /**
865      * Removes all listeners from the set listening to frame updates for this animation.
866      */
removeAllUpdateListeners()867     public void removeAllUpdateListeners() {
868         if (mUpdateListeners == null) {
869             return;
870         }
871         mUpdateListeners.clear();
872         mUpdateListeners = null;
873     }
874 
875     /**
876      * Removes a listener from the set listening to frame updates for this animation.
877      *
878      * @param listener the listener to be removed from the current set of update listeners
879      * for this animation.
880      */
removeUpdateListener(AnimatorUpdateListener listener)881     public void removeUpdateListener(AnimatorUpdateListener listener) {
882         if (mUpdateListeners == null) {
883             return;
884         }
885         mUpdateListeners.remove(listener);
886         if (mUpdateListeners.size() == 0) {
887             mUpdateListeners = null;
888         }
889     }
890 
891 
892     /**
893      * The time interpolator used in calculating the elapsed fraction of this animation. The
894      * interpolator determines whether the animation runs with linear or non-linear motion,
895      * such as acceleration and deceleration. The default value is
896      * {@link android.view.animation.AccelerateDecelerateInterpolator}
897      *
898      * @param value the interpolator to be used by this animation. A value of <code>null</code>
899      * will result in linear interpolation.
900      */
901     @Override
setInterpolator(TimeInterpolator value)902     public void setInterpolator(TimeInterpolator value) {
903         if (value != null) {
904             mInterpolator = value;
905         } else {
906             mInterpolator = new LinearInterpolator();
907         }
908     }
909 
910     /**
911      * Returns the timing interpolator that this ValueAnimator uses.
912      *
913      * @return The timing interpolator for this ValueAnimator.
914      */
915     @Override
getInterpolator()916     public TimeInterpolator getInterpolator() {
917         return mInterpolator;
918     }
919 
920     /**
921      * The type evaluator to be used when calculating the animated values of this animation.
922      * The system will automatically assign a float or int evaluator based on the type
923      * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
924      * are not one of these primitive types, or if different evaluation is desired (such as is
925      * necessary with int values that represent colors), a custom evaluator needs to be assigned.
926      * For example, when running an animation on color values, the {@link ArgbEvaluator}
927      * should be used to get correct RGB color interpolation.
928      *
929      * <p>If this ValueAnimator has only one set of values being animated between, this evaluator
930      * will be used for that set. If there are several sets of values being animated, which is
931      * the case if PropertyValuesHolder objects were set on the ValueAnimator, then the evaluator
932      * is assigned just to the first PropertyValuesHolder object.</p>
933      *
934      * @param value the evaluator to be used this animation
935      */
setEvaluator(TypeEvaluator value)936     public void setEvaluator(TypeEvaluator value) {
937         if (value != null && mValues != null && mValues.length > 0) {
938             mValues[0].setEvaluator(value);
939         }
940     }
941 
notifyStartListeners()942     private void notifyStartListeners() {
943         if (mListeners != null && !mStartListenersCalled) {
944             ArrayList<AnimatorListener> tmpListeners =
945                     (ArrayList<AnimatorListener>) mListeners.clone();
946             int numListeners = tmpListeners.size();
947             for (int i = 0; i < numListeners; ++i) {
948                 tmpListeners.get(i).onAnimationStart(this);
949             }
950         }
951         mStartListenersCalled = true;
952     }
953 
954     /**
955      * Start the animation playing. This version of start() takes a boolean flag that indicates
956      * whether the animation should play in reverse. The flag is usually false, but may be set
957      * to true if called from the reverse() method.
958      *
959      * <p>The animation started by calling this method will be run on the thread that called
960      * this method. This thread should have a Looper on it (a runtime exception will be thrown if
961      * this is not the case). Also, if the animation will animate
962      * properties of objects in the view hierarchy, then the calling thread should be the UI
963      * thread for that view hierarchy.</p>
964      *
965      * @param playBackwards Whether the ValueAnimator should start playing in reverse.
966      */
start(boolean playBackwards)967     private void start(boolean playBackwards) {
968         if (Looper.myLooper() == null) {
969             throw new AndroidRuntimeException("Animators may only be run on Looper threads");
970         }
971         mReversing = playBackwards;
972         // Special case: reversing from seek-to-0 should act as if not seeked at all.
973         if (playBackwards && mSeekFraction != -1 && mSeekFraction != 0) {
974             if (mRepeatCount == INFINITE) {
975                 // Calculate the fraction of the current iteration.
976                 float fraction = (float) (mSeekFraction - Math.floor(mSeekFraction));
977                 mSeekFraction = 1 - fraction;
978             } else {
979                 mSeekFraction = 1 + mRepeatCount - mSeekFraction;
980             }
981         }
982         mStarted = true;
983         mPaused = false;
984         mRunning = false;
985         // Resets mLastFrameTime when start() is called, so that if the animation was running,
986         // calling start() would put the animation in the
987         // started-but-not-yet-reached-the-first-frame phase.
988         mLastFrameTime = 0;
989         AnimationHandler animationHandler = AnimationHandler.getInstance();
990         animationHandler.addAnimationFrameCallback(this, (long) (mStartDelay * sDurationScale));
991 
992         if (mStartDelay == 0 || mSeekFraction >= 0) {
993             // If there's no start delay, init the animation and notify start listeners right away
994             // to be consistent with the previous behavior. Otherwise, postpone this until the first
995             // frame after the start delay.
996             startAnimation();
997             if (mSeekFraction == -1) {
998                 // No seek, start at play time 0. Note that the reason we are not using fraction 0
999                 // is because for animations with 0 duration, we want to be consistent with pre-N
1000                 // behavior: skip to the final value immediately.
1001                 setCurrentPlayTime(0);
1002             } else {
1003                 setCurrentFraction(mSeekFraction);
1004             }
1005         }
1006     }
1007 
1008     @Override
start()1009     public void start() {
1010         start(false);
1011     }
1012 
1013     @Override
cancel()1014     public void cancel() {
1015         if (Looper.myLooper() == null) {
1016             throw new AndroidRuntimeException("Animators may only be run on Looper threads");
1017         }
1018 
1019         // If end has already been requested, through a previous end() or cancel() call, no-op
1020         // until animation starts again.
1021         if (mAnimationEndRequested) {
1022             return;
1023         }
1024 
1025         // Only cancel if the animation is actually running or has been started and is about
1026         // to run
1027         // Only notify listeners if the animator has actually started
1028         if ((mStarted || mRunning) && mListeners != null) {
1029             if (!mRunning) {
1030                 // If it's not yet running, then start listeners weren't called. Call them now.
1031                 notifyStartListeners();
1032             }
1033             ArrayList<AnimatorListener> tmpListeners =
1034                     (ArrayList<AnimatorListener>) mListeners.clone();
1035             for (AnimatorListener listener : tmpListeners) {
1036                 listener.onAnimationCancel(this);
1037             }
1038         }
1039         endAnimation();
1040 
1041     }
1042 
1043     @Override
end()1044     public void end() {
1045         if (Looper.myLooper() == null) {
1046             throw new AndroidRuntimeException("Animators may only be run on Looper threads");
1047         }
1048         if (!mRunning) {
1049             // Special case if the animation has not yet started; get it ready for ending
1050             startAnimation();
1051             mStarted = true;
1052         } else if (!mInitialized) {
1053             initAnimation();
1054         }
1055         animateValue(shouldPlayBackward(mRepeatCount) ? 0f : 1f);
1056         endAnimation();
1057     }
1058 
1059     @Override
resume()1060     public void resume() {
1061         if (Looper.myLooper() == null) {
1062             throw new AndroidRuntimeException("Animators may only be resumed from the same " +
1063                     "thread that the animator was started on");
1064         }
1065         if (mPaused && !mResumed) {
1066             mResumed = true;
1067             if (mPauseTime > 0) {
1068                 AnimationHandler handler = AnimationHandler.getInstance();
1069                 handler.addAnimationFrameCallback(this, 0);
1070             }
1071         }
1072         super.resume();
1073     }
1074 
1075     @Override
pause()1076     public void pause() {
1077         boolean previouslyPaused = mPaused;
1078         super.pause();
1079         if (!previouslyPaused && mPaused) {
1080             mPauseTime = -1;
1081             mResumed = false;
1082         }
1083     }
1084 
1085     @Override
isRunning()1086     public boolean isRunning() {
1087         return mRunning;
1088     }
1089 
1090     @Override
isStarted()1091     public boolean isStarted() {
1092         return mStarted;
1093     }
1094 
1095     /**
1096      * Plays the ValueAnimator in reverse. If the animation is already running,
1097      * it will stop itself and play backwards from the point reached when reverse was called.
1098      * If the animation is not currently running, then it will start from the end and
1099      * play backwards. This behavior is only set for the current animation; future playing
1100      * of the animation will use the default behavior of playing forward.
1101      */
1102     @Override
reverse()1103     public void reverse() {
1104         if (isPulsingInternal()) {
1105             long currentTime = AnimationUtils.currentAnimationTimeMillis();
1106             long currentPlayTime = currentTime - mStartTime;
1107             long timeLeft = getScaledDuration() - currentPlayTime;
1108             mStartTime = currentTime - timeLeft;
1109             mStartTimeCommitted = true; // do not allow start time to be compensated for jank
1110             mReversing = !mReversing;
1111         } else if (mStarted) {
1112             mReversing = !mReversing;
1113             end();
1114         } else {
1115             start(true);
1116         }
1117     }
1118 
1119     /**
1120      * @hide
1121      */
1122     @Override
canReverse()1123     public boolean canReverse() {
1124         return true;
1125     }
1126 
1127     /**
1128      * Called internally to end an animation by removing it from the animations list. Must be
1129      * called on the UI thread.
1130      */
endAnimation()1131     private void endAnimation() {
1132         if (mAnimationEndRequested) {
1133             return;
1134         }
1135         AnimationHandler handler = AnimationHandler.getInstance();
1136         handler.removeCallback(this);
1137 
1138         mAnimationEndRequested = true;
1139         mPaused = false;
1140         if ((mStarted || mRunning) && mListeners != null) {
1141             if (!mRunning) {
1142                 // If it's not yet running, then start listeners weren't called. Call them now.
1143                 notifyStartListeners();
1144              }
1145             ArrayList<AnimatorListener> tmpListeners =
1146                     (ArrayList<AnimatorListener>) mListeners.clone();
1147             int numListeners = tmpListeners.size();
1148             for (int i = 0; i < numListeners; ++i) {
1149                 tmpListeners.get(i).onAnimationEnd(this);
1150             }
1151         }
1152         mRunning = false;
1153         mStarted = false;
1154         mStartListenersCalled = false;
1155         mReversing = false;
1156         mLastFrameTime = 0;
1157         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
1158             Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
1159                     System.identityHashCode(this));
1160         }
1161     }
1162 
1163     /**
1164      * Called internally to start an animation by adding it to the active animations list. Must be
1165      * called on the UI thread.
1166      */
startAnimation()1167     private void startAnimation() {
1168         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
1169             Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
1170                     System.identityHashCode(this));
1171         }
1172 
1173         mAnimationEndRequested = false;
1174         initAnimation();
1175         mRunning = true;
1176         if (mSeekFraction >= 0) {
1177             mOverallFraction = mSeekFraction;
1178         } else {
1179             mOverallFraction = 0f;
1180         }
1181         if (mListeners != null) {
1182             notifyStartListeners();
1183         }
1184     }
1185 
1186     /**
1187      * Internal only: This tracks whether the animation has gotten on the animation loop. Note
1188      * this is different than {@link #isRunning()} in that the latter tracks the time after start()
1189      * is called (or after start delay if any), which may be before the animation loop starts.
1190      */
isPulsingInternal()1191     private boolean isPulsingInternal() {
1192         return mLastFrameTime > 0;
1193     }
1194 
1195     /**
1196      * Returns the name of this animator for debugging purposes.
1197      */
getNameForTrace()1198     String getNameForTrace() {
1199         return "animator";
1200     }
1201 
1202     /**
1203      * Applies an adjustment to the animation to compensate for jank between when
1204      * the animation first ran and when the frame was drawn.
1205      * @hide
1206      */
commitAnimationFrame(long frameTime)1207     public void commitAnimationFrame(long frameTime) {
1208         if (!mStartTimeCommitted) {
1209             mStartTimeCommitted = true;
1210             long adjustment = frameTime - mLastFrameTime;
1211             if (adjustment > 0) {
1212                 mStartTime += adjustment;
1213                 if (DEBUG) {
1214                     Log.d(TAG, "Adjusted start time by " + adjustment + " ms: " + toString());
1215                 }
1216             }
1217         }
1218     }
1219 
1220     /**
1221      * This internal function processes a single animation frame for a given animation. The
1222      * currentTime parameter is the timing pulse sent by the handler, used to calculate the
1223      * elapsed duration, and therefore
1224      * the elapsed fraction, of the animation. The return value indicates whether the animation
1225      * should be ended (which happens when the elapsed time of the animation exceeds the
1226      * animation's duration, including the repeatCount).
1227      *
1228      * @param currentTime The current time, as tracked by the static timing handler
1229      * @return true if the animation's duration, including any repetitions due to
1230      * <code>repeatCount</code> has been exceeded and the animation should be ended.
1231      */
animateBasedOnTime(long currentTime)1232     boolean animateBasedOnTime(long currentTime) {
1233         boolean done = false;
1234         if (mRunning) {
1235             final long scaledDuration = getScaledDuration();
1236             final float fraction = scaledDuration > 0 ?
1237                     (float)(currentTime - mStartTime) / scaledDuration : 1f;
1238             final float lastFraction = mOverallFraction;
1239             final boolean newIteration = (int) fraction > (int) lastFraction;
1240             final boolean lastIterationFinished = (fraction >= mRepeatCount + 1) &&
1241                     (mRepeatCount != INFINITE);
1242             if (scaledDuration == 0) {
1243                 // 0 duration animator, ignore the repeat count and skip to the end
1244                 done = true;
1245             } else if (newIteration && !lastIterationFinished) {
1246                 // Time to repeat
1247                 if (mListeners != null) {
1248                     int numListeners = mListeners.size();
1249                     for (int i = 0; i < numListeners; ++i) {
1250                         mListeners.get(i).onAnimationRepeat(this);
1251                     }
1252                 }
1253             } else if (lastIterationFinished) {
1254                 done = true;
1255             }
1256             mOverallFraction = clampFraction(fraction);
1257             float currentIterationFraction = getCurrentIterationFraction(mOverallFraction);
1258             animateValue(currentIterationFraction);
1259         }
1260         return done;
1261     }
1262 
1263     /**
1264      * Processes a frame of the animation, adjusting the start time if needed.
1265      *
1266      * @param frameTime The frame time.
1267      * @return true if the animation has ended.
1268      * @hide
1269      */
doAnimationFrame(long frameTime)1270     public final void doAnimationFrame(long frameTime) {
1271         AnimationHandler handler = AnimationHandler.getInstance();
1272         if (mLastFrameTime == 0) {
1273             // First frame
1274             handler.addOneShotCommitCallback(this);
1275             if (mStartDelay > 0) {
1276                 startAnimation();
1277             }
1278             if (mSeekFraction < 0) {
1279                 mStartTime = frameTime;
1280             } else {
1281                 long seekTime = (long) (getScaledDuration() * mSeekFraction);
1282                 mStartTime = frameTime - seekTime;
1283                 mSeekFraction = -1;
1284             }
1285             mStartTimeCommitted = false; // allow start time to be compensated for jank
1286         }
1287         mLastFrameTime = frameTime;
1288         if (mPaused) {
1289             mPauseTime = frameTime;
1290             handler.removeCallback(this);
1291             return;
1292         } else if (mResumed) {
1293             mResumed = false;
1294             if (mPauseTime > 0) {
1295                 // Offset by the duration that the animation was paused
1296                 mStartTime += (frameTime - mPauseTime);
1297                 mStartTimeCommitted = false; // allow start time to be compensated for jank
1298             }
1299             handler.addOneShotCommitCallback(this);
1300         }
1301         // The frame time might be before the start time during the first frame of
1302         // an animation.  The "current time" must always be on or after the start
1303         // time to avoid animating frames at negative time intervals.  In practice, this
1304         // is very rare and only happens when seeking backwards.
1305         final long currentTime = Math.max(frameTime, mStartTime);
1306         boolean finished = animateBasedOnTime(currentTime);
1307 
1308         if (finished) {
1309             endAnimation();
1310         }
1311     }
1312 
1313     /**
1314      * Returns the current animation fraction, which is the elapsed/interpolated fraction used in
1315      * the most recent frame update on the animation.
1316      *
1317      * @return Elapsed/interpolated fraction of the animation.
1318      */
getAnimatedFraction()1319     public float getAnimatedFraction() {
1320         return mCurrentFraction;
1321     }
1322 
1323     /**
1324      * This method is called with the elapsed fraction of the animation during every
1325      * animation frame. This function turns the elapsed fraction into an interpolated fraction
1326      * and then into an animated value (from the evaluator. The function is called mostly during
1327      * animation updates, but it is also called when the <code>end()</code>
1328      * function is called, to set the final value on the property.
1329      *
1330      * <p>Overrides of this method must call the superclass to perform the calculation
1331      * of the animated value.</p>
1332      *
1333      * @param fraction The elapsed fraction of the animation.
1334      */
1335     @CallSuper
animateValue(float fraction)1336     void animateValue(float fraction) {
1337         fraction = mInterpolator.getInterpolation(fraction);
1338         mCurrentFraction = fraction;
1339         int numValues = mValues.length;
1340         for (int i = 0; i < numValues; ++i) {
1341             mValues[i].calculateValue(fraction);
1342         }
1343         if (mUpdateListeners != null) {
1344             int numListeners = mUpdateListeners.size();
1345             for (int i = 0; i < numListeners; ++i) {
1346                 mUpdateListeners.get(i).onAnimationUpdate(this);
1347             }
1348         }
1349     }
1350 
1351     @Override
clone()1352     public ValueAnimator clone() {
1353         final ValueAnimator anim = (ValueAnimator) super.clone();
1354         if (mUpdateListeners != null) {
1355             anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(mUpdateListeners);
1356         }
1357         anim.mSeekFraction = -1;
1358         anim.mReversing = false;
1359         anim.mInitialized = false;
1360         anim.mStarted = false;
1361         anim.mRunning = false;
1362         anim.mPaused = false;
1363         anim.mResumed = false;
1364         anim.mStartListenersCalled = false;
1365         anim.mStartTime = 0;
1366         anim.mStartTimeCommitted = false;
1367         anim.mAnimationEndRequested = false;
1368         anim.mPauseTime = 0;
1369         anim.mLastFrameTime = 0;
1370         anim.mOverallFraction = 0;
1371         anim.mCurrentFraction = 0;
1372 
1373         PropertyValuesHolder[] oldValues = mValues;
1374         if (oldValues != null) {
1375             int numValues = oldValues.length;
1376             anim.mValues = new PropertyValuesHolder[numValues];
1377             anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
1378             for (int i = 0; i < numValues; ++i) {
1379                 PropertyValuesHolder newValuesHolder = oldValues[i].clone();
1380                 anim.mValues[i] = newValuesHolder;
1381                 anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder);
1382             }
1383         }
1384         return anim;
1385     }
1386 
1387     /**
1388      * Implementors of this interface can add themselves as update listeners
1389      * to an <code>ValueAnimator</code> instance to receive callbacks on every animation
1390      * frame, after the current frame's values have been calculated for that
1391      * <code>ValueAnimator</code>.
1392      */
1393     public static interface AnimatorUpdateListener {
1394         /**
1395          * <p>Notifies the occurrence of another frame of the animation.</p>
1396          *
1397          * @param animation The animation which was repeated.
1398          */
onAnimationUpdate(ValueAnimator animation)1399         void onAnimationUpdate(ValueAnimator animation);
1400 
1401     }
1402 
1403     /**
1404      * Return the number of animations currently running.
1405      *
1406      * Used by StrictMode internally to annotate violations.
1407      * May be called on arbitrary threads!
1408      *
1409      * @hide
1410      */
getCurrentAnimationsCount()1411     public static int getCurrentAnimationsCount() {
1412         return AnimationHandler.getAnimationCount();
1413     }
1414 
1415     @Override
toString()1416     public String toString() {
1417         String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode());
1418         if (mValues != null) {
1419             for (int i = 0; i < mValues.length; ++i) {
1420                 returnVal += "\n    " + mValues[i].toString();
1421             }
1422         }
1423         return returnVal;
1424     }
1425 
1426     /**
1427      * <p>Whether or not the ValueAnimator is allowed to run asynchronously off of
1428      * the UI thread. This is a hint that informs the ValueAnimator that it is
1429      * OK to run the animation off-thread, however ValueAnimator may decide
1430      * that it must run the animation on the UI thread anyway. For example if there
1431      * is an {@link AnimatorUpdateListener} the animation will run on the UI thread,
1432      * regardless of the value of this hint.</p>
1433      *
1434      * <p>Regardless of whether or not the animation runs asynchronously, all
1435      * listener callbacks will be called on the UI thread.</p>
1436      *
1437      * <p>To be able to use this hint the following must be true:</p>
1438      * <ol>
1439      * <li>{@link #getAnimatedFraction()} is not needed (it will return undefined values).</li>
1440      * <li>The animator is immutable while {@link #isStarted()} is true. Requests
1441      *    to change values, duration, delay, etc... may be ignored.</li>
1442      * <li>Lifecycle callback events may be asynchronous. Events such as
1443      *    {@link Animator.AnimatorListener#onAnimationEnd(Animator)} or
1444      *    {@link Animator.AnimatorListener#onAnimationRepeat(Animator)} may end up delayed
1445      *    as they must be posted back to the UI thread, and any actions performed
1446      *    by those callbacks (such as starting new animations) will not happen
1447      *    in the same frame.</li>
1448      * <li>State change requests ({@link #cancel()}, {@link #end()}, {@link #reverse()}, etc...)
1449      *    may be asynchronous. It is guaranteed that all state changes that are
1450      *    performed on the UI thread in the same frame will be applied as a single
1451      *    atomic update, however that frame may be the current frame,
1452      *    the next frame, or some future frame. This will also impact the observed
1453      *    state of the Animator. For example, {@link #isStarted()} may still return true
1454      *    after a call to {@link #end()}. Using the lifecycle callbacks is preferred over
1455      *    queries to {@link #isStarted()}, {@link #isRunning()}, and {@link #isPaused()}
1456      *    for this reason.</li>
1457      * </ol>
1458      * @hide
1459      */
1460     @Override
setAllowRunningAsynchronously(boolean mayRunAsync)1461     public void setAllowRunningAsynchronously(boolean mayRunAsync) {
1462         // It is up to subclasses to support this, if they can.
1463     }
1464 }
1465