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     private 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 float 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 ofFloat(float... values) {
    294         ValueAnimator anim = new ValueAnimator();
    295         anim.setFloatValues(values);
    296         return anim;
    297     }
    298 
    299     /**
    300      * Constructs and returns a ValueAnimator that animates between the values
    301      * specified in the PropertyValuesHolder objects.
    302      *
    303      * @param values A set of PropertyValuesHolder objects whose values will be animated
    304      * between over time.
    305      * @return A ValueAnimator object that is set up to animate between the given values.
    306      */
    307     public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
    308         ValueAnimator anim = new ValueAnimator();
    309         anim.setValues(values);
    310         return anim;
    311     }
    312     /**
    313      * Constructs and returns a ValueAnimator that animates between Object values. A single
    314      * value implies that that value is the one being animated to. However, this is not typically
    315      * useful in a ValueAnimator object because there is no way for the object to determine the
    316      * starting value for the animation (unlike ObjectAnimator, which can derive that value
    317      * from the target object and property being animated). Therefore, there should typically
    318      * be two or more values.
    319      *
    320      * <p>Since ValueAnimator does not know how to animate between arbitrary Objects, this
    321      * factory method also takes a TypeEvaluator object that the ValueAnimator will use
    322      * to perform that interpolation.
    323      *
    324      * @param evaluator A TypeEvaluator that will be called on each animation frame to
    325      * provide the ncessry interpolation between the Object values to derive the animated
    326      * value.
    327      * @param values A set of values that the animation will animate between over time.
    328      * @return A ValueAnimator object that is set up to animate between the given values.
    329      */
    330     public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
    331         ValueAnimator anim = new ValueAnimator();
    332         anim.setObjectValues(values);
    333         anim.setEvaluator(evaluator);
    334         return anim;
    335     }
    336 
    337     /**
    338      * Sets int values that will be animated between. A single
    339      * value implies that that value is the one being animated to. However, this is not typically
    340      * useful in a ValueAnimator object because there is no way for the object to determine the
    341      * starting value for the animation (unlike ObjectAnimator, which can derive that value
    342      * from the target object and property being animated). Therefore, there should typically
    343      * be two or more values.
    344      *
    345      * <p>If there are already multiple sets of values defined for this ValueAnimator via more
    346      * than one PropertyValuesHolder object, this method will set the values for the first
    347      * of those objects.</p>
    348      *
    349      * @param values A set of values that the animation will animate between over time.
    350      */
    351     public void setIntValues(int... values) {
    352         if (values == null || values.length == 0) {
    353             return;
    354         }
    355         if (mValues == null || mValues.length == 0) {
    356             setValues(PropertyValuesHolder.ofInt("", values));
    357         } else {
    358             PropertyValuesHolder valuesHolder = mValues[0];
    359             valuesHolder.setIntValues(values);
    360         }
    361         // New property/values/target should cause re-initialization prior to starting
    362         mInitialized = false;
    363     }
    364 
    365     /**
    366      * Sets float 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 setFloatValues(float... values) {
    380         if (values == null || values.length == 0) {
    381             return;
    382         }
    383         if (mValues == null || mValues.length == 0) {
    384             setValues(PropertyValuesHolder.ofFloat("", values));
    385         } else {
    386             PropertyValuesHolder valuesHolder = mValues[0];
    387             valuesHolder.setFloatValues(values);
    388         }
    389         // New property/values/target should cause re-initialization prior to starting
    390         mInitialized = false;
    391     }
    392 
    393     /**
    394      * Sets the values to animate between for this animation. 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      * <p>There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate
    406      * between these value objects. ValueAnimator only knows how to interpolate between the
    407      * primitive types specified in the other setValues() methods.</p>
    408      *
    409      * @param values The set of values to animate between.
    410      */
    411     public void setObjectValues(Object... values) {
    412         if (values == null || values.length == 0) {
    413             return;
    414         }
    415         if (mValues == null || mValues.length == 0) {
    416             setValues(PropertyValuesHolder.ofObject("", null, values));
    417         } else {
    418             PropertyValuesHolder valuesHolder = mValues[0];
    419             valuesHolder.setObjectValues(values);
    420         }
    421         // New property/values/target should cause re-initialization prior to starting
    422         mInitialized = false;
    423     }
    424 
    425     /**
    426      * Sets the values, per property, being animated between. This function is called internally
    427      * by the constructors of ValueAnimator that take a list of values. But a ValueAnimator can
    428      * be constructed without values and this method can be called to set the values manually
    429      * instead.
    430      *
    431      * @param values The set of values, per property, being animated between.
    432      */
    433     public void setValues(PropertyValuesHolder... values) {
    434         int numValues = values.length;
    435         mValues = values;
    436         mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
    437         for (int i = 0; i < numValues; ++i) {
    438             PropertyValuesHolder valuesHolder = values[i];
    439             mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
    440         }
    441         // New property/values/target should cause re-initialization prior to starting
    442         mInitialized = false;
    443     }
    444 
    445     /**
    446      * Returns the values that this ValueAnimator animates between. These values are stored in
    447      * PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list
    448      * of value objects instead.
    449      *
    450      * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the
    451      * values, per property, that define the animation.
    452      */
    453     public PropertyValuesHolder[] getValues() {
    454         return mValues;
    455     }
    456 
    457     /**
    458      * This function is called immediately before processing the first animation
    459      * frame of an animation. If there is a nonzero <code>startDelay</code>, the
    460      * function is called after that delay ends.
    461      * It takes care of the final initialization steps for the
    462      * animation.
    463      *
    464      *  <p>Overrides of this method should call the superclass method to ensure
    465      *  that internal mechanisms for the animation are set up correctly.</p>
    466      */
    467     void initAnimation() {
    468         if (!mInitialized) {
    469             int numValues = mValues.length;
    470             for (int i = 0; i < numValues; ++i) {
    471                 mValues[i].init();
    472             }
    473             mInitialized = true;
    474         }
    475     }
    476 
    477 
    478     /**
    479      * Sets the length of the animation. The default duration is 300 milliseconds.
    480      *
    481      * @param duration The length of the animation, in milliseconds. This value cannot
    482      * be negative.
    483      * @return ValueAnimator The object called with setDuration(). This return
    484      * value makes it easier to compose statements together that construct and then set the
    485      * duration, as in <code>ValueAnimator.ofInt(0, 10).setDuration(500).start()</code>.
    486      */
    487     public ValueAnimator setDuration(long duration) {
    488         if (duration < 0) {
    489             throw new IllegalArgumentException("Animators cannot have negative duration: " +
    490                     duration);
    491         }
    492         mUnscaledDuration = duration;
    493         mDuration = (long)(duration * sDurationScale);
    494         return this;
    495     }
    496 
    497     /**
    498      * Gets the length of the animation. The default duration is 300 milliseconds.
    499      *
    500      * @return The length of the animation, in milliseconds.
    501      */
    502     public long getDuration() {
    503         return mUnscaledDuration;
    504     }
    505 
    506     /**
    507      * Sets the position of the animation to the specified point in time. This time should
    508      * be between 0 and the total duration of the animation, including any repetition. If
    509      * the animation has not yet been started, then it will not advance forward after it is
    510      * set to this time; it will simply set the time to this value and perform any appropriate
    511      * actions based on that time. If the animation is already running, then setCurrentPlayTime()
    512      * will set the current playing time to this value and continue playing from that point.
    513      *
    514      * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
    515      */
    516     public void setCurrentPlayTime(long playTime) {
    517         initAnimation();
    518         long currentTime = AnimationUtils.currentAnimationTimeMillis();
    519         if (mPlayingState != RUNNING) {
    520             mSeekTime = playTime;
    521             mPlayingState = SEEKED;
    522         }
    523         mStartTime = currentTime - playTime;
    524         doAnimationFrame(currentTime);
    525     }
    526 
    527     /**
    528      * Gets the current position of the animation in time, which is equal to the current
    529      * time minus the time that the animation started. An animation that is not yet started will
    530      * return a value of zero.
    531      *
    532      * @return The current position in time of the animation.
    533      */
    534     public long getCurrentPlayTime() {
    535         if (!mInitialized || mPlayingState == STOPPED) {
    536             return 0;
    537         }
    538         return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
    539     }
    540 
    541     /**
    542      * This custom, static handler handles the timing pulse that is shared by
    543      * all active animations. This approach ensures that the setting of animation
    544      * values will happen on the UI thread and that all animations will share
    545      * the same times for calculating their values, which makes synchronizing
    546      * animations possible.
    547      *
    548      * The handler uses the Choreographer for executing periodic callbacks.
    549      *
    550      * @hide
    551      */
    552     @SuppressWarnings("unchecked")
    553     protected static class AnimationHandler implements Runnable {
    554         // The per-thread list of all active animations
    555         /** @hide */
    556         protected final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>();
    557 
    558         // Used in doAnimationFrame() to avoid concurrent modifications of mAnimations
    559         private final ArrayList<ValueAnimator> mTmpAnimations = new ArrayList<ValueAnimator>();
    560 
    561         // The per-thread set of animations to be started on the next animation frame
    562         /** @hide */
    563         protected final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
    564 
    565         /**
    566          * Internal per-thread collections used to avoid set collisions as animations start and end
    567          * while being processed.
    568          * @hide
    569          */
    570         protected final ArrayList<ValueAnimator> mDelayedAnims = new ArrayList<ValueAnimator>();
    571         private final ArrayList<ValueAnimator> mEndingAnims = new ArrayList<ValueAnimator>();
    572         private final ArrayList<ValueAnimator> mReadyAnims = new ArrayList<ValueAnimator>();
    573 
    574         private final Choreographer mChoreographer;
    575         private boolean mAnimationScheduled;
    576 
    577         private AnimationHandler() {
    578             mChoreographer = Choreographer.getInstance();
    579         }
    580 
    581         /**
    582          * Start animating on the next frame.
    583          */
    584         public void start() {
    585             scheduleAnimation();
    586         }
    587 
    588         private void doAnimationFrame(long frameTime) {
    589             // mPendingAnimations holds any animations that have requested to be started
    590             // We're going to clear mPendingAnimations, but starting animation may
    591             // cause more to be added to the pending list (for example, if one animation
    592             // starting triggers another starting). So we loop until mPendingAnimations
    593             // is empty.
    594             while (mPendingAnimations.size() > 0) {
    595                 ArrayList<ValueAnimator> pendingCopy =
    596                         (ArrayList<ValueAnimator>) mPendingAnimations.clone();
    597                 mPendingAnimations.clear();
    598                 int count = pendingCopy.size();
    599                 for (int i = 0; i < count; ++i) {
    600                     ValueAnimator anim = pendingCopy.get(i);
    601                     // If the animation has a startDelay, place it on the delayed list
    602                     if (anim.mStartDelay == 0) {
    603                         anim.startAnimation(this);
    604                     } else {
    605                         mDelayedAnims.add(anim);
    606                     }
    607                 }
    608             }
    609             // Next, process animations currently sitting on the delayed queue, adding
    610             // them to the active animations if they are ready
    611             int numDelayedAnims = mDelayedAnims.size();
    612             for (int i = 0; i < numDelayedAnims; ++i) {
    613                 ValueAnimator anim = mDelayedAnims.get(i);
    614                 if (anim.delayedAnimationFrame(frameTime)) {
    615                     mReadyAnims.add(anim);
    616                 }
    617             }
    618             int numReadyAnims = mReadyAnims.size();
    619             if (numReadyAnims > 0) {
    620                 for (int i = 0; i < numReadyAnims; ++i) {
    621                     ValueAnimator anim = mReadyAnims.get(i);
    622                     anim.startAnimation(this);
    623                     anim.mRunning = true;
    624                     mDelayedAnims.remove(anim);
    625                 }
    626                 mReadyAnims.clear();
    627             }
    628 
    629             // Now process all active animations. The return value from animationFrame()
    630             // tells the handler whether it should now be ended
    631             int numAnims = mAnimations.size();
    632             for (int i = 0; i < numAnims; ++i) {
    633                 mTmpAnimations.add(mAnimations.get(i));
    634             }
    635             for (int i = 0; i < numAnims; ++i) {
    636                 ValueAnimator anim = mTmpAnimations.get(i);
    637                 if (mAnimations.contains(anim) && anim.doAnimationFrame(frameTime)) {
    638                     mEndingAnims.add(anim);
    639                 }
    640             }
    641             mTmpAnimations.clear();
    642             if (mEndingAnims.size() > 0) {
    643                 for (int i = 0; i < mEndingAnims.size(); ++i) {
    644                     mEndingAnims.get(i).endAnimation(this);
    645                 }
    646                 mEndingAnims.clear();
    647             }
    648 
    649             // If there are still active or delayed animations, schedule a future call to
    650             // onAnimate to process the next frame of the animations.
    651             if (!mAnimations.isEmpty() || !mDelayedAnims.isEmpty()) {
    652                 scheduleAnimation();
    653             }
    654         }
    655 
    656         // Called by the Choreographer.
    657         @Override
    658         public void run() {
    659             mAnimationScheduled = false;
    660             doAnimationFrame(mChoreographer.getFrameTime());
    661         }
    662 
    663         private void scheduleAnimation() {
    664             if (!mAnimationScheduled) {
    665                 mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
    666                 mAnimationScheduled = true;
    667             }
    668         }
    669     }
    670 
    671     /**
    672      * The amount of time, in milliseconds, to delay starting the animation after
    673      * {@link #start()} is called.
    674      *
    675      * @return the number of milliseconds to delay running the animation
    676      */
    677     public long getStartDelay() {
    678         return mUnscaledStartDelay;
    679     }
    680 
    681     /**
    682      * The amount of time, in milliseconds, to delay starting the animation after
    683      * {@link #start()} is called.
    684 
    685      * @param startDelay The amount of the delay, in milliseconds
    686      */
    687     public void setStartDelay(long startDelay) {
    688         this.mStartDelay = (long)(startDelay * sDurationScale);
    689         mUnscaledStartDelay = startDelay;
    690     }
    691 
    692     /**
    693      * The amount of time, in milliseconds, between each frame of the animation. This is a
    694      * requested time that the animation will attempt to honor, but the actual delay between
    695      * frames may be different, depending on system load and capabilities. This is a static
    696      * function because the same delay will be applied to all animations, since they are all
    697      * run off of a single timing loop.
    698      *
    699      * The frame delay may be ignored when the animation system uses an external timing
    700      * source, such as the display refresh rate (vsync), to govern animations.
    701      *
    702      * @return the requested time between frames, in milliseconds
    703      */
    704     public static long getFrameDelay() {
    705         return Choreographer.getFrameDelay();
    706     }
    707 
    708     /**
    709      * The amount of time, in milliseconds, between each frame of the animation. This is a
    710      * requested time that the animation will attempt to honor, but the actual delay between
    711      * frames may be different, depending on system load and capabilities. This is a static
    712      * function because the same delay will be applied to all animations, since they are all
    713      * run off of a single timing loop.
    714      *
    715      * The frame delay may be ignored when the animation system uses an external timing
    716      * source, such as the display refresh rate (vsync), to govern animations.
    717      *
    718      * @param frameDelay the requested time between frames, in milliseconds
    719      */
    720     public static void setFrameDelay(long frameDelay) {
    721         Choreographer.setFrameDelay(frameDelay);
    722     }
    723 
    724     /**
    725      * The most recent value calculated by this <code>ValueAnimator</code> when there is just one
    726      * property being animated. This value is only sensible while the animation is running. The main
    727      * purpose for this read-only property is to retrieve the value from the <code>ValueAnimator</code>
    728      * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
    729      * is called during each animation frame, immediately after the value is calculated.
    730      *
    731      * @return animatedValue The value most recently calculated by this <code>ValueAnimator</code> for
    732      * the single property being animated. If there are several properties being animated
    733      * (specified by several PropertyValuesHolder objects in the constructor), this function
    734      * returns the animated value for the first of those objects.
    735      */
    736     public Object getAnimatedValue() {
    737         if (mValues != null && mValues.length > 0) {
    738             return mValues[0].getAnimatedValue();
    739         }
    740         // Shouldn't get here; should always have values unless ValueAnimator was set up wrong
    741         return null;
    742     }
    743 
    744     /**
    745      * The most recent value calculated by this <code>ValueAnimator</code> for <code>propertyName</code>.
    746      * The main purpose for this read-only property is to retrieve the value from the
    747      * <code>ValueAnimator</code> during a call to
    748      * {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
    749      * is called during each animation frame, immediately after the value is calculated.
    750      *
    751      * @return animatedValue The value most recently calculated for the named property
    752      * by this <code>ValueAnimator</code>.
    753      */
    754     public Object getAnimatedValue(String propertyName) {
    755         PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
    756         if (valuesHolder != null) {
    757             return valuesHolder.getAnimatedValue();
    758         } else {
    759             // At least avoid crashing if called with bogus propertyName
    760             return null;
    761         }
    762     }
    763 
    764     /**
    765      * Sets how many times the animation should be repeated. If the repeat
    766      * count is 0, the animation is never repeated. If the repeat count is
    767      * greater than 0 or {@link #INFINITE}, the repeat mode will be taken
    768      * into account. The repeat count is 0 by default.
    769      *
    770      * @param value the number of times the animation should be repeated
    771      */
    772     public void setRepeatCount(int value) {
    773         mRepeatCount = value;
    774     }
    775     /**
    776      * Defines how many times the animation should repeat. The default value
    777      * is 0.
    778      *
    779      * @return the number of times the animation should repeat, or {@link #INFINITE}
    780      */
    781     public int getRepeatCount() {
    782         return mRepeatCount;
    783     }
    784 
    785     /**
    786      * Defines what this animation should do when it reaches the end. This
    787      * setting is applied only when the repeat count is either greater than
    788      * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}.
    789      *
    790      * @param value {@link #RESTART} or {@link #REVERSE}
    791      */
    792     public void setRepeatMode(int value) {
    793         mRepeatMode = value;
    794     }
    795 
    796     /**
    797      * Defines what this animation should do when it reaches the end.
    798      *
    799      * @return either one of {@link #REVERSE} or {@link #RESTART}
    800      */
    801     public int getRepeatMode() {
    802         return mRepeatMode;
    803     }
    804 
    805     /**
    806      * Adds a listener to the set of listeners that are sent update events through the life of
    807      * an animation. This method is called on all listeners for every frame of the animation,
    808      * after the values for the animation have been calculated.
    809      *
    810      * @param listener the listener to be added to the current set of listeners for this animation.
    811      */
    812     public void addUpdateListener(AnimatorUpdateListener listener) {
    813         if (mUpdateListeners == null) {
    814             mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
    815         }
    816         mUpdateListeners.add(listener);
    817     }
    818 
    819     /**
    820      * Removes all listeners from the set listening to frame updates for this animation.
    821      */
    822     public void removeAllUpdateListeners() {
    823         if (mUpdateListeners == null) {
    824             return;
    825         }
    826         mUpdateListeners.clear();
    827         mUpdateListeners = null;
    828     }
    829 
    830     /**
    831      * Removes a listener from the set listening to frame updates for this animation.
    832      *
    833      * @param listener the listener to be removed from the current set of update listeners
    834      * for this animation.
    835      */
    836     public void removeUpdateListener(AnimatorUpdateListener listener) {
    837         if (mUpdateListeners == null) {
    838             return;
    839         }
    840         mUpdateListeners.remove(listener);
    841         if (mUpdateListeners.size() == 0) {
    842             mUpdateListeners = null;
    843         }
    844     }
    845 
    846 
    847     /**
    848      * The time interpolator used in calculating the elapsed fraction of this animation. The
    849      * interpolator determines whether the animation runs with linear or non-linear motion,
    850      * such as acceleration and deceleration. The default value is
    851      * {@link android.view.animation.AccelerateDecelerateInterpolator}
    852      *
    853      * @param value the interpolator to be used by this animation. A value of <code>null</code>
    854      * will result in linear interpolation.
    855      */
    856     @Override
    857     public void setInterpolator(TimeInterpolator value) {
    858         if (value != null) {
    859             mInterpolator = value;
    860         } else {
    861             mInterpolator = new LinearInterpolator();
    862         }
    863     }
    864 
    865     /**
    866      * Returns the timing interpolator that this ValueAnimator uses.
    867      *
    868      * @return The timing interpolator for this ValueAnimator.
    869      */
    870     @Override
    871     public TimeInterpolator getInterpolator() {
    872         return mInterpolator;
    873     }
    874 
    875     /**
    876      * The type evaluator to be used when calculating the animated values of this animation.
    877      * The system will automatically assign a float or int evaluator based on the type
    878      * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
    879      * are not one of these primitive types, or if different evaluation is desired (such as is
    880      * necessary with int values that represent colors), a custom evaluator needs to be assigned.
    881      * For example, when running an animation on color values, the {@link ArgbEvaluator}
    882      * should be used to get correct RGB color interpolation.
    883      *
    884      * <p>If this ValueAnimator has only one set of values being animated between, this evaluator
    885      * will be used for that set. If there are several sets of values being animated, which is
    886      * the case if PropertyValuesHolder objects were set on the ValueAnimator, then the evaluator
    887      * is assigned just to the first PropertyValuesHolder object.</p>
    888      *
    889      * @param value the evaluator to be used this animation
    890      */
    891     public void setEvaluator(TypeEvaluator value) {
    892         if (value != null && mValues != null && mValues.length > 0) {
    893             mValues[0].setEvaluator(value);
    894         }
    895     }
    896 
    897     private void notifyStartListeners() {
    898         if (mListeners != null && !mStartListenersCalled) {
    899             ArrayList<AnimatorListener> tmpListeners =
    900                     (ArrayList<AnimatorListener>) mListeners.clone();
    901             int numListeners = tmpListeners.size();
    902             for (int i = 0; i < numListeners; ++i) {
    903                 tmpListeners.get(i).onAnimationStart(this);
    904             }
    905         }
    906         mStartListenersCalled = true;
    907     }
    908 
    909     /**
    910      * Start the animation playing. This version of start() takes a boolean flag that indicates
    911      * whether the animation should play in reverse. The flag is usually false, but may be set
    912      * to true if called from the reverse() method.
    913      *
    914      * <p>The animation started by calling this method will be run on the thread that called
    915      * this method. This thread should have a Looper on it (a runtime exception will be thrown if
    916      * this is not the case). Also, if the animation will animate
    917      * properties of objects in the view hierarchy, then the calling thread should be the UI
    918      * thread for that view hierarchy.</p>
    919      *
    920      * @param playBackwards Whether the ValueAnimator should start playing in reverse.
    921      */
    922     private void start(boolean playBackwards) {
    923         if (Looper.myLooper() == null) {
    924             throw new AndroidRuntimeException("Animators may only be run on Looper threads");
    925         }
    926         mPlayingBackwards = playBackwards;
    927         mCurrentIteration = 0;
    928         mPlayingState = STOPPED;
    929         mStarted = true;
    930         mStartedDelay = false;
    931         mPaused = false;
    932         AnimationHandler animationHandler = getOrCreateAnimationHandler();
    933         animationHandler.mPendingAnimations.add(this);
    934         if (mStartDelay == 0) {
    935             // This sets the initial value of the animation, prior to actually starting it running
    936             setCurrentPlayTime(0);
    937             mPlayingState = STOPPED;
    938             mRunning = true;
    939             notifyStartListeners();
    940         }
    941         animationHandler.start();
    942     }
    943 
    944     @Override
    945     public void start() {
    946         start(false);
    947     }
    948 
    949     @Override
    950     public void cancel() {
    951         // Only cancel if the animation is actually running or has been started and is about
    952         // to run
    953         AnimationHandler handler = getOrCreateAnimationHandler();
    954         if (mPlayingState != STOPPED
    955                 || handler.mPendingAnimations.contains(this)
    956                 || handler.mDelayedAnims.contains(this)) {
    957             // Only notify listeners if the animator has actually started
    958             if ((mStarted || mRunning) && mListeners != null) {
    959                 if (!mRunning) {
    960                     // If it's not yet running, then start listeners weren't called. Call them now.
    961                     notifyStartListeners();
    962                 }
    963                 ArrayList<AnimatorListener> tmpListeners =
    964                         (ArrayList<AnimatorListener>) mListeners.clone();
    965                 for (AnimatorListener listener : tmpListeners) {
    966                     listener.onAnimationCancel(this);
    967                 }
    968             }
    969             endAnimation(handler);
    970         }
    971     }
    972 
    973     @Override
    974     public void end() {
    975         AnimationHandler handler = getOrCreateAnimationHandler();
    976         if (!handler.mAnimations.contains(this) && !handler.mPendingAnimations.contains(this)) {
    977             // Special case if the animation has not yet started; get it ready for ending
    978             mStartedDelay = false;
    979             startAnimation(handler);
    980             mStarted = true;
    981         } else if (!mInitialized) {
    982             initAnimation();
    983         }
    984         animateValue(mPlayingBackwards ? 0f : 1f);
    985         endAnimation(handler);
    986     }
    987 
    988     @Override
    989     public void resume() {
    990         if (mPaused) {
    991             mResumed = true;
    992         }
    993         super.resume();
    994     }
    995 
    996     @Override
    997     public void pause() {
    998         boolean previouslyPaused = mPaused;
    999         super.pause();
   1000         if (!previouslyPaused && mPaused) {
   1001             mPauseTime = -1;
   1002             mResumed = false;
   1003         }
   1004     }
   1005 
   1006     @Override
   1007     public boolean isRunning() {
   1008         return (mPlayingState == RUNNING || mRunning);
   1009     }
   1010 
   1011     @Override
   1012     public boolean isStarted() {
   1013         return mStarted;
   1014     }
   1015 
   1016     /**
   1017      * Plays the ValueAnimator in reverse. If the animation is already running,
   1018      * it will stop itself and play backwards from the point reached when reverse was called.
   1019      * If the animation is not currently running, then it will start from the end and
   1020      * play backwards. This behavior is only set for the current animation; future playing
   1021      * of the animation will use the default behavior of playing forward.
   1022      */
   1023     public void reverse() {
   1024         mPlayingBackwards = !mPlayingBackwards;
   1025         if (mPlayingState == RUNNING) {
   1026             long currentTime = AnimationUtils.currentAnimationTimeMillis();
   1027             long currentPlayTime = currentTime - mStartTime;
   1028             long timeLeft = mDuration - currentPlayTime;
   1029             mStartTime = currentTime - timeLeft;
   1030         } else if (mStarted) {
   1031             end();
   1032         } else {
   1033             start(true);
   1034         }
   1035     }
   1036 
   1037     /**
   1038      * Called internally to end an animation by removing it from the animations list. Must be
   1039      * called on the UI thread.
   1040      */
   1041     private void endAnimation(AnimationHandler handler) {
   1042         handler.mAnimations.remove(this);
   1043         handler.mPendingAnimations.remove(this);
   1044         handler.mDelayedAnims.remove(this);
   1045         mPlayingState = STOPPED;
   1046         mPaused = false;
   1047         if ((mStarted || mRunning) && mListeners != null) {
   1048             if (!mRunning) {
   1049                 // If it's not yet running, then start listeners weren't called. Call them now.
   1050                 notifyStartListeners();
   1051              }
   1052             ArrayList<AnimatorListener> tmpListeners =
   1053                     (ArrayList<AnimatorListener>) mListeners.clone();
   1054             int numListeners = tmpListeners.size();
   1055             for (int i = 0; i < numListeners; ++i) {
   1056                 tmpListeners.get(i).onAnimationEnd(this);
   1057             }
   1058         }
   1059         mRunning = false;
   1060         mStarted = false;
   1061         mStartListenersCalled = false;
   1062         mPlayingBackwards = false;
   1063         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
   1064             Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
   1065                     System.identityHashCode(this));
   1066         }
   1067     }
   1068 
   1069     /**
   1070      * Called internally to start an animation by adding it to the active animations list. Must be
   1071      * called on the UI thread.
   1072      */
   1073     private void startAnimation(AnimationHandler handler) {
   1074         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
   1075             Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
   1076                     System.identityHashCode(this));
   1077         }
   1078         initAnimation();
   1079         handler.mAnimations.add(this);
   1080         if (mStartDelay > 0 && mListeners != null) {
   1081             // Listeners were already notified in start() if startDelay is 0; this is
   1082             // just for delayed animations
   1083             notifyStartListeners();
   1084         }
   1085     }
   1086 
   1087     /**
   1088      * Returns the name of this animator for debugging purposes.
   1089      */
   1090     String getNameForTrace() {
   1091         return "animator";
   1092     }
   1093 
   1094 
   1095     /**
   1096      * Internal function called to process an animation frame on an animation that is currently
   1097      * sleeping through its <code>startDelay</code> phase. The return value indicates whether it
   1098      * should be woken up and put on the active animations queue.
   1099      *
   1100      * @param currentTime The current animation time, used to calculate whether the animation
   1101      * has exceeded its <code>startDelay</code> and should be started.
   1102      * @return True if the animation's <code>startDelay</code> has been exceeded and the animation
   1103      * should be added to the set of active animations.
   1104      */
   1105     private boolean delayedAnimationFrame(long currentTime) {
   1106         if (!mStartedDelay) {
   1107             mStartedDelay = true;
   1108             mDelayStartTime = currentTime;
   1109         } else {
   1110             if (mPaused) {
   1111                 if (mPauseTime < 0) {
   1112                     mPauseTime = currentTime;
   1113                 }
   1114                 return false;
   1115             } else if (mResumed) {
   1116                 mResumed = false;
   1117                 if (mPauseTime > 0) {
   1118                     // Offset by the duration that the animation was paused
   1119                     mDelayStartTime += (currentTime - mPauseTime);
   1120                 }
   1121             }
   1122             long deltaTime = currentTime - mDelayStartTime;
   1123             if (deltaTime > mStartDelay) {
   1124                 // startDelay ended - start the anim and record the
   1125                 // mStartTime appropriately
   1126                 mStartTime = currentTime - (deltaTime - mStartDelay);
   1127                 mPlayingState = RUNNING;
   1128                 return true;
   1129             }
   1130         }
   1131         return false;
   1132     }
   1133 
   1134     /**
   1135      * This internal function processes a single animation frame for a given animation. The
   1136      * currentTime parameter is the timing pulse sent by the handler, used to calculate the
   1137      * elapsed duration, and therefore
   1138      * the elapsed fraction, of the animation. The return value indicates whether the animation
   1139      * should be ended (which happens when the elapsed time of the animation exceeds the
   1140      * animation's duration, including the repeatCount).
   1141      *
   1142      * @param currentTime The current time, as tracked by the static timing handler
   1143      * @return true if the animation's duration, including any repetitions due to
   1144      * <code>repeatCount</code>, has been exceeded and the animation should be ended.
   1145      */
   1146     boolean animationFrame(long currentTime) {
   1147         boolean done = false;
   1148         switch (mPlayingState) {
   1149         case RUNNING:
   1150         case SEEKED:
   1151             float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
   1152             if (fraction >= 1f) {
   1153                 if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
   1154                     // Time to repeat
   1155                     if (mListeners != null) {
   1156                         int numListeners = mListeners.size();
   1157                         for (int i = 0; i < numListeners; ++i) {
   1158                             mListeners.get(i).onAnimationRepeat(this);
   1159                         }
   1160                     }
   1161                     if (mRepeatMode == REVERSE) {
   1162                         mPlayingBackwards = !mPlayingBackwards;
   1163                     }
   1164                     mCurrentIteration += (int)fraction;
   1165                     fraction = fraction % 1f;
   1166                     mStartTime += mDuration;
   1167                 } else {
   1168                     done = true;
   1169                     fraction = Math.min(fraction, 1.0f);
   1170                 }
   1171             }
   1172             if (mPlayingBackwards) {
   1173                 fraction = 1f - fraction;
   1174             }
   1175             animateValue(fraction);
   1176             break;
   1177         }
   1178 
   1179         return done;
   1180     }
   1181 
   1182     /**
   1183      * Processes a frame of the animation, adjusting the start time if needed.
   1184      *
   1185      * @param frameTime The frame time.
   1186      * @return true if the animation has ended.
   1187      */
   1188     final boolean doAnimationFrame(long frameTime) {
   1189         if (mPlayingState == STOPPED) {
   1190             mPlayingState = RUNNING;
   1191             if (mSeekTime < 0) {
   1192                 mStartTime = frameTime;
   1193             } else {
   1194                 mStartTime = frameTime - mSeekTime;
   1195                 // Now that we're playing, reset the seek time
   1196                 mSeekTime = -1;
   1197             }
   1198         }
   1199         if (mPaused) {
   1200             if (mPauseTime < 0) {
   1201                 mPauseTime = frameTime;
   1202             }
   1203             return false;
   1204         } else if (mResumed) {
   1205             mResumed = false;
   1206             if (mPauseTime > 0) {
   1207                 // Offset by the duration that the animation was paused
   1208                 mStartTime += (frameTime - mPauseTime);
   1209             }
   1210         }
   1211         // The frame time might be before the start time during the first frame of
   1212         // an animation.  The "current time" must always be on or after the start
   1213         // time to avoid animating frames at negative time intervals.  In practice, this
   1214         // is very rare and only happens when seeking backwards.
   1215         final long currentTime = Math.max(frameTime, mStartTime);
   1216         return animationFrame(currentTime);
   1217     }
   1218 
   1219     /**
   1220      * Returns the current animation fraction, which is the elapsed/interpolated fraction used in
   1221      * the most recent frame update on the animation.
   1222      *
   1223      * @return Elapsed/interpolated fraction of the animation.
   1224      */
   1225     public float getAnimatedFraction() {
   1226         return mCurrentFraction;
   1227     }
   1228 
   1229     /**
   1230      * This method is called with the elapsed fraction of the animation during every
   1231      * animation frame. This function turns the elapsed fraction into an interpolated fraction
   1232      * and then into an animated value (from the evaluator. The function is called mostly during
   1233      * animation updates, but it is also called when the <code>end()</code>
   1234      * function is called, to set the final value on the property.
   1235      *
   1236      * <p>Overrides of this method must call the superclass to perform the calculation
   1237      * of the animated value.</p>
   1238      *
   1239      * @param fraction The elapsed fraction of the animation.
   1240      */
   1241     void animateValue(float fraction) {
   1242         fraction = mInterpolator.getInterpolation(fraction);
   1243         mCurrentFraction = fraction;
   1244         int numValues = mValues.length;
   1245         for (int i = 0; i < numValues; ++i) {
   1246             mValues[i].calculateValue(fraction);
   1247         }
   1248         if (mUpdateListeners != null) {
   1249             int numListeners = mUpdateListeners.size();
   1250             for (int i = 0; i < numListeners; ++i) {
   1251                 mUpdateListeners.get(i).onAnimationUpdate(this);
   1252             }
   1253         }
   1254     }
   1255 
   1256     @Override
   1257     public ValueAnimator clone() {
   1258         final ValueAnimator anim = (ValueAnimator) super.clone();
   1259         if (mUpdateListeners != null) {
   1260             ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners;
   1261             anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
   1262             int numListeners = oldListeners.size();
   1263             for (int i = 0; i < numListeners; ++i) {
   1264                 anim.mUpdateListeners.add(oldListeners.get(i));
   1265             }
   1266         }
   1267         anim.mSeekTime = -1;
   1268         anim.mPlayingBackwards = false;
   1269         anim.mCurrentIteration = 0;
   1270         anim.mInitialized = false;
   1271         anim.mPlayingState = STOPPED;
   1272         anim.mStartedDelay = false;
   1273         PropertyValuesHolder[] oldValues = mValues;
   1274         if (oldValues != null) {
   1275             int numValues = oldValues.length;
   1276             anim.mValues = new PropertyValuesHolder[numValues];
   1277             anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
   1278             for (int i = 0; i < numValues; ++i) {
   1279                 PropertyValuesHolder newValuesHolder = oldValues[i].clone();
   1280                 anim.mValues[i] = newValuesHolder;
   1281                 anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder);
   1282             }
   1283         }
   1284         return anim;
   1285     }
   1286 
   1287     /**
   1288      * Implementors of this interface can add themselves as update listeners
   1289      * to an <code>ValueAnimator</code> instance to receive callbacks on every animation
   1290      * frame, after the current frame's values have been calculated for that
   1291      * <code>ValueAnimator</code>.
   1292      */
   1293     public static interface AnimatorUpdateListener {
   1294         /**
   1295          * <p>Notifies the occurrence of another frame of the animation.</p>
   1296          *
   1297          * @param animation The animation which was repeated.
   1298          */
   1299         void onAnimationUpdate(ValueAnimator animation);
   1300 
   1301     }
   1302 
   1303     /**
   1304      * Return the number of animations currently running.
   1305      *
   1306      * Used by StrictMode internally to annotate violations.
   1307      * May be called on arbitrary threads!
   1308      *
   1309      * @hide
   1310      */
   1311     public static int getCurrentAnimationsCount() {
   1312         AnimationHandler handler = sAnimationHandler.get();
   1313         return handler != null ? handler.mAnimations.size() : 0;
   1314     }
   1315 
   1316     /**
   1317      * Clear all animations on this thread, without canceling or ending them.
   1318      * This should be used with caution.
   1319      *
   1320      * @hide
   1321      */
   1322     public static void clearAllAnimations() {
   1323         AnimationHandler handler = sAnimationHandler.get();
   1324         if (handler != null) {
   1325             handler.mAnimations.clear();
   1326             handler.mPendingAnimations.clear();
   1327             handler.mDelayedAnims.clear();
   1328         }
   1329     }
   1330 
   1331     private static AnimationHandler getOrCreateAnimationHandler() {
   1332         AnimationHandler handler = sAnimationHandler.get();
   1333         if (handler == null) {
   1334             handler = new AnimationHandler();
   1335             sAnimationHandler.set(handler);
   1336         }
   1337         return handler;
   1338     }
   1339 
   1340     @Override
   1341     public String toString() {
   1342         String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode());
   1343         if (mValues != null) {
   1344             for (int i = 0; i < mValues.length; ++i) {
   1345                 returnVal += "\n    " + mValues[i].toString();
   1346             }
   1347         }
   1348         return returnVal;
   1349     }
   1350 }
   1351