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