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