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