FileDocCategorySizeDatePackage
ValueAnimator.javaAPI DocAndroid 5.1 API61365Thu Mar 12 22:22:08 GMT 2015android.animation

ValueAnimator

public class ValueAnimator extends Animator
This class provides a simple timing engine for running animations which calculate animated values and set them on target objects.

There is a single timing pulse that all animations use. It runs in a custom handler to ensure that property changes happen on the UI thread.

By default, ValueAnimator uses non-linear time interpolation, via the {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates out of an animation. This behavior can be changed by calling {@link ValueAnimator#setInterpolator(TimeInterpolator)}.

Developer Guides

For more information about animating with {@code ValueAnimator}, read the Property Animation developer guide.

Fields Summary
private static float
sDurationScale
Internal constants
static final int
STOPPED
Values used with internal variable mPlayingState to indicate the current state of an animation.
static final int
RUNNING
static final int
SEEKED
long
mStartTime
Internal variables NOTE: This object implements the clone() method, making a deep copy of any referenced objects. As other non-trivial fields are added to this class, make sure to add logic to clone() to make deep copies of them.
float
mSeekFraction
Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked to a value.
private long
mPauseTime
Set on the next frame after pause() is called, used to calculate a new startTime or delayStartTime which allows the animator to continue from the point at which it was paused. If negative, has not yet been set.
private boolean
mResumed
Set when an animator is resumed. This triggers logic in the next frame which actually resumes the animator.
protected static ThreadLocal
sAnimationHandler
private static final TimeInterpolator
sDefaultInterpolator
private boolean
mPlayingBackwards
Used to indicate whether the animation is currently playing in reverse. This causes the elapsed fraction to be inverted to calculate the appropriate values.
private boolean
mReversing
Flag to indicate whether this animator is playing in reverse mode, specifically by being started or interrupted by a call to reverse(). This flag is different than mPlayingBackwards, which indicates merely whether the current iteration of the animator is playing in reverse. It is used in corner cases to determine proper end behavior.
private int
mCurrentIteration
This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the repeatCount (if repeatCount!=INFINITE), the animation ends
private float
mCurrentFraction
Tracks current elapsed/eased fraction, for querying in getAnimatedFraction().
private boolean
mStartedDelay
Tracks whether a startDelay'd animation has begun playing through the startDelay.
private long
mDelayStartTime
Tracks the time at which the animation began playing through its startDelay. This is different from the mStartTime variable, which is used to track when the animation became active (which is when the startDelay expired and the animation was added to the active animations list).
int
mPlayingState
Flag that represents the current state of the animation. Used to figure out when to start an animation (if state == STOPPED). Also used to end an animation that has been cancel()'d or end()'d since the last animation frame. Possible values are STOPPED, RUNNING, SEEKED.
private boolean
mRunning
Additional playing state to indicate whether an animator has been start()'d. There is some lag between a call to start() and the first animation frame. We should still note that the animation has been started, even if it's first animation frame has not yet happened, and reflect that state in isRunning(). Note that delayed animations are different: they are not started until their first animation frame, which occurs after their delay elapses.
private boolean
mStarted
Additional playing state to indicate whether an animator has been start()'d, whether or not there is a nonzero startDelay.
private boolean
mStartListenersCalled
Tracks whether we've notified listeners of the onAnimationStart() event. This can be complex to keep track of since we notify listeners at different times depending on startDelay and whether start() was called before end().
boolean
mInitialized
Flag that denotes whether the animation is set up and ready to go. Used to set up animation that has not yet been started.
private long
mDuration
private long
mUnscaledDuration
private long
mStartDelay
private long
mUnscaledStartDelay
private int
mRepeatCount
private int
mRepeatMode
The type of repetition that will occur when repeatMode is nonzero. RESTART means the animation will start from the beginning on every new cycle. REVERSE means the animation will reverse directions on each iteration.
private TimeInterpolator
mInterpolator
The time interpolator to be used. The elapsed fraction of the animation will be passed through this interpolator to calculate the interpolated fraction, which is then used to calculate the animated values.
ArrayList
mUpdateListeners
The set of listeners to be sent events through the life of an animation.
PropertyValuesHolder[]
mValues
The property/value sets being animated.
HashMap
mValuesMap
A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values by property name during calls to getAnimatedValue(String).
public static final int
RESTART
When the animation reaches the end and repeatCount is INFINITE or a positive value, the animation restarts from the beginning.
public static final int
REVERSE
When the animation reaches the end and repeatCount is INFINITE or a positive value, the animation reverses direction on every iteration.
public static final int
INFINITE
This value used used with the {@link #setRepeatCount(int)} property to repeat the animation indefinitely.
Constructors Summary
public ValueAnimator()
Creates a new ValueAnimator object. This default constructor is primarily for use internally; the factory methods which take parameters are more generally useful.

    
Methods Summary
public voidaddUpdateListener(android.animation.ValueAnimator$AnimatorUpdateListener listener)
Adds a listener to the set of listeners that are sent update events through the life of an animation. This method is called on all listeners for every frame of the animation, after the values for the animation have been calculated.

param
listener the listener to be added to the current set of listeners for this animation.

        if (mUpdateListeners == null) {
            mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
        }
        mUpdateListeners.add(listener);
    
voidanimateValue(float fraction)
This method is called with the elapsed fraction of the animation during every animation frame. This function turns the elapsed fraction into an interpolated fraction and then into an animated value (from the evaluator. The function is called mostly during animation updates, but it is also called when the end() function is called, to set the final value on the property.

Overrides of this method must call the superclass to perform the calculation of the animated value.

param
fraction The elapsed fraction of the animation.

        fraction = mInterpolator.getInterpolation(fraction);
        mCurrentFraction = fraction;
        int numValues = mValues.length;
        for (int i = 0; i < numValues; ++i) {
            mValues[i].calculateValue(fraction);
        }
        if (mUpdateListeners != null) {
            int numListeners = mUpdateListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                mUpdateListeners.get(i).onAnimationUpdate(this);
            }
        }
    
booleananimationFrame(long currentTime)
This internal function processes a single animation frame for a given animation. The currentTime parameter is the timing pulse sent by the handler, used to calculate the elapsed duration, and therefore the elapsed fraction, of the animation. The return value indicates whether the animation should be ended (which happens when the elapsed time of the animation exceeds the animation's duration, including the repeatCount).

param
currentTime The current time, as tracked by the static timing handler
return
true if the animation's duration, including any repetitions due to repeatCount, has been exceeded and the animation should be ended.

        boolean done = false;
        switch (mPlayingState) {
        case RUNNING:
        case SEEKED:
            float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
            if (mDuration == 0 && mRepeatCount != INFINITE) {
                // Skip to the end
                mCurrentIteration = mRepeatCount;
                if (!mReversing) {
                    mPlayingBackwards = false;
                }
            }
            if (fraction >= 1f) {
                if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
                    // Time to repeat
                    if (mListeners != null) {
                        int numListeners = mListeners.size();
                        for (int i = 0; i < numListeners; ++i) {
                            mListeners.get(i).onAnimationRepeat(this);
                        }
                    }
                    if (mRepeatMode == REVERSE) {
                        mPlayingBackwards = !mPlayingBackwards;
                    }
                    mCurrentIteration += (int) fraction;
                    fraction = fraction % 1f;
                    mStartTime += mDuration;
                } else {
                    done = true;
                    fraction = Math.min(fraction, 1.0f);
                }
            }
            if (mPlayingBackwards) {
                fraction = 1f - fraction;
            }
            animateValue(fraction);
            break;
        }

        return done;
    
public booleancanReverse()

hide

        return true;
    
public voidcancel()

        // Only cancel if the animation is actually running or has been started and is about
        // to run
        AnimationHandler handler = getOrCreateAnimationHandler();
        if (mPlayingState != STOPPED
                || handler.mPendingAnimations.contains(this)
                || handler.mDelayedAnims.contains(this)) {
            // Only notify listeners if the animator has actually started
            if ((mStarted || mRunning) && mListeners != null) {
                if (!mRunning) {
                    // If it's not yet running, then start listeners weren't called. Call them now.
                    notifyStartListeners();
                }
                ArrayList<AnimatorListener> tmpListeners =
                        (ArrayList<AnimatorListener>) mListeners.clone();
                for (AnimatorListener listener : tmpListeners) {
                    listener.onAnimationCancel(this);
                }
            }
            endAnimation(handler);
        }
    
public static voidclearAllAnimations()
Clear all animations on this thread, without canceling or ending them. This should be used with caution.

hide

        AnimationHandler handler = sAnimationHandler.get();
        if (handler != null) {
            handler.mAnimations.clear();
            handler.mPendingAnimations.clear();
            handler.mDelayedAnims.clear();
        }
    
public android.animation.ValueAnimatorclone()

        final ValueAnimator anim = (ValueAnimator) super.clone();
        if (mUpdateListeners != null) {
            anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(mUpdateListeners);
        }
        anim.mSeekFraction = -1;
        anim.mPlayingBackwards = false;
        anim.mReversing = false;
        anim.mCurrentIteration = 0;
        anim.mInitialized = false;
        anim.mPlayingState = STOPPED;
        anim.mStartedDelay = false;
        PropertyValuesHolder[] oldValues = mValues;
        if (oldValues != null) {
            int numValues = oldValues.length;
            anim.mValues = new PropertyValuesHolder[numValues];
            anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
            for (int i = 0; i < numValues; ++i) {
                PropertyValuesHolder newValuesHolder = oldValues[i].clone();
                anim.mValues[i] = newValuesHolder;
                anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder);
            }
        }
        return anim;
    
private booleandelayedAnimationFrame(long currentTime)
Internal function called to process an animation frame on an animation that is currently sleeping through its startDelay phase. The return value indicates whether it should be woken up and put on the active animations queue.

param
currentTime The current animation time, used to calculate whether the animation has exceeded its startDelay and should be started.
return
True if the animation's startDelay has been exceeded and the animation should be added to the set of active animations.

        if (!mStartedDelay) {
            mStartedDelay = true;
            mDelayStartTime = currentTime;
        }
        if (mPaused) {
            if (mPauseTime < 0) {
                mPauseTime = currentTime;
            }
            return false;
        } else if (mResumed) {
            mResumed = false;
            if (mPauseTime > 0) {
                // Offset by the duration that the animation was paused
                mDelayStartTime += (currentTime - mPauseTime);
            }
        }
        long deltaTime = currentTime - mDelayStartTime;
        if (deltaTime > mStartDelay) {
            // startDelay ended - start the anim and record the
            // mStartTime appropriately
            mStartTime = currentTime - (deltaTime - mStartDelay);
            mPlayingState = RUNNING;
            return true;
        }
        return false;
    
final booleandoAnimationFrame(long frameTime)
Processes a frame of the animation, adjusting the start time if needed.

param
frameTime The frame time.
return
true if the animation has ended.

        if (mPlayingState == STOPPED) {
            mPlayingState = RUNNING;
            if (mSeekFraction < 0) {
                mStartTime = frameTime;
            } else {
                long seekTime = (long) (mDuration * mSeekFraction);
                mStartTime = frameTime - seekTime;
                mSeekFraction = -1;
            }
        }
        if (mPaused) {
            if (mPauseTime < 0) {
                mPauseTime = frameTime;
            }
            return false;
        } else if (mResumed) {
            mResumed = false;
            if (mPauseTime > 0) {
                // Offset by the duration that the animation was paused
                mStartTime += (frameTime - mPauseTime);
            }
        }
        // The frame time might be before the start time during the first frame of
        // an animation.  The "current time" must always be on or after the start
        // time to avoid animating frames at negative time intervals.  In practice, this
        // is very rare and only happens when seeking backwards.
        final long currentTime = Math.max(frameTime, mStartTime);
        return animationFrame(currentTime);
    
public voidend()

        AnimationHandler handler = getOrCreateAnimationHandler();
        if (!handler.mAnimations.contains(this) && !handler.mPendingAnimations.contains(this)) {
            // Special case if the animation has not yet started; get it ready for ending
            mStartedDelay = false;
            startAnimation(handler);
            mStarted = true;
        } else if (!mInitialized) {
            initAnimation();
        }
        animateValue(mPlayingBackwards ? 0f : 1f);
        endAnimation(handler);
    
protected voidendAnimation(android.animation.ValueAnimator$AnimationHandler handler)
Called internally to end an animation by removing it from the animations list. Must be called on the UI thread.

hide

        handler.mAnimations.remove(this);
        handler.mPendingAnimations.remove(this);
        handler.mDelayedAnims.remove(this);
        mPlayingState = STOPPED;
        mPaused = false;
        if ((mStarted || mRunning) && mListeners != null) {
            if (!mRunning) {
                // If it's not yet running, then start listeners weren't called. Call them now.
                notifyStartListeners();
             }
            ArrayList<AnimatorListener> tmpListeners =
                    (ArrayList<AnimatorListener>) mListeners.clone();
            int numListeners = tmpListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                tmpListeners.get(i).onAnimationEnd(this);
            }
        }
        mRunning = false;
        mStarted = false;
        mStartListenersCalled = false;
        mPlayingBackwards = false;
        mReversing = false;
        mCurrentIteration = 0;
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
                    System.identityHashCode(this));
        }
    
public floatgetAnimatedFraction()
Returns the current animation fraction, which is the elapsed/interpolated fraction used in the most recent frame update on the animation.

return
Elapsed/interpolated fraction of the animation.

        return mCurrentFraction;
    
public java.lang.ObjectgetAnimatedValue()
The most recent value calculated by this ValueAnimator when there is just one property being animated. This value is only sensible while the animation is running. The main purpose for this read-only property is to retrieve the value from the ValueAnimator during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which is called during each animation frame, immediately after the value is calculated.

return
animatedValue The value most recently calculated by this ValueAnimator for the single property being animated. If there are several properties being animated (specified by several PropertyValuesHolder objects in the constructor), this function returns the animated value for the first of those objects.

        if (mValues != null && mValues.length > 0) {
            return mValues[0].getAnimatedValue();
        }
        // Shouldn't get here; should always have values unless ValueAnimator was set up wrong
        return null;
    
public java.lang.ObjectgetAnimatedValue(java.lang.String propertyName)
The most recent value calculated by this ValueAnimator for propertyName. The main purpose for this read-only property is to retrieve the value from the ValueAnimator during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which is called during each animation frame, immediately after the value is calculated.

return
animatedValue The value most recently calculated for the named property by this ValueAnimator.

        PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
        if (valuesHolder != null) {
            return valuesHolder.getAnimatedValue();
        } else {
            // At least avoid crashing if called with bogus propertyName
            return null;
        }
    
public static intgetCurrentAnimationsCount()
Return the number of animations currently running. Used by StrictMode internally to annotate violations. May be called on arbitrary threads!

hide

        AnimationHandler handler = sAnimationHandler.get();
        return handler != null ? handler.mAnimations.size() : 0;
    
public longgetCurrentPlayTime()
Gets the current position of the animation in time, which is equal to the current time minus the time that the animation started. An animation that is not yet started will return a value of zero.

return
The current position in time of the animation.

        if (!mInitialized || mPlayingState == STOPPED) {
            return 0;
        }
        return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
    
public longgetDuration()
Gets the length of the animation. The default duration is 300 milliseconds.

return
The length of the animation, in milliseconds.

        return mUnscaledDuration;
    
public static floatgetDurationScale()

hide

        return sDurationScale;
    
public static longgetFrameDelay()
The amount of time, in milliseconds, between each frame of the animation. This is a requested time that the animation will attempt to honor, but the actual delay between frames may be different, depending on system load and capabilities. This is a static function because the same delay will be applied to all animations, since they are all run off of a single timing loop. The frame delay may be ignored when the animation system uses an external timing source, such as the display refresh rate (vsync), to govern animations.

return
the requested time between frames, in milliseconds

        return Choreographer.getFrameDelay();
    
public TimeInterpolatorgetInterpolator()
Returns the timing interpolator that this ValueAnimator uses.

return
The timing interpolator for this ValueAnimator.

        return mInterpolator;
    
java.lang.StringgetNameForTrace()
Returns the name of this animator for debugging purposes.

        return "animator";
    
private static android.animation.ValueAnimator$AnimationHandlergetOrCreateAnimationHandler()

        AnimationHandler handler = sAnimationHandler.get();
        if (handler == null) {
            handler = new AnimationHandler();
            sAnimationHandler.set(handler);
        }
        return handler;
    
public intgetRepeatCount()
Defines how many times the animation should repeat. The default value is 0.

return
the number of times the animation should repeat, or {@link #INFINITE}

        return mRepeatCount;
    
public intgetRepeatMode()
Defines what this animation should do when it reaches the end.

return
either one of {@link #REVERSE} or {@link #RESTART}

        return mRepeatMode;
    
public longgetStartDelay()
The amount of time, in milliseconds, to delay starting the animation after {@link #start()} is called.

return
the number of milliseconds to delay running the animation

        return mUnscaledStartDelay;
    
public PropertyValuesHolder[]getValues()
Returns the values that this ValueAnimator animates between. These values are stored in PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list of value objects instead.

return
PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the values, per property, that define the animation.

        return mValues;
    
voidinitAnimation()
This function is called immediately before processing the first animation frame of an animation. If there is a nonzero startDelay, the function is called after that delay ends. It takes care of the final initialization steps for the animation.

Overrides of this method should call the superclass method to ensure that internal mechanisms for the animation are set up correctly.

        if (!mInitialized) {
            int numValues = mValues.length;
            for (int i = 0; i < numValues; ++i) {
                mValues[i].init();
            }
            mInitialized = true;
        }
    
public booleanisRunning()

        return (mPlayingState == RUNNING || mRunning);
    
public booleanisStarted()

        return mStarted;
    
private voidnotifyStartListeners()

        if (mListeners != null && !mStartListenersCalled) {
            ArrayList<AnimatorListener> tmpListeners =
                    (ArrayList<AnimatorListener>) mListeners.clone();
            int numListeners = tmpListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                tmpListeners.get(i).onAnimationStart(this);
            }
        }
        mStartListenersCalled = true;
    
public static android.animation.ValueAnimatorofArgb(int values)
Constructs and returns a ValueAnimator that animates between color values. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

param
values A set of values that the animation will animate between over time.
return
A ValueAnimator object that is set up to animate between the given values.

        ValueAnimator anim = new ValueAnimator();
        anim.setIntValues(values);
        anim.setEvaluator(ArgbEvaluator.getInstance());
        return anim;
    
public static android.animation.ValueAnimatorofFloat(float values)
Constructs and returns a ValueAnimator that animates between float values. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

param
values A set of values that the animation will animate between over time.
return
A ValueAnimator object that is set up to animate between the given values.

        ValueAnimator anim = new ValueAnimator();
        anim.setFloatValues(values);
        return anim;
    
public static android.animation.ValueAnimatorofInt(int values)
Constructs and returns a ValueAnimator that animates between int values. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

param
values A set of values that the animation will animate between over time.
return
A ValueAnimator object that is set up to animate between the given values.

        ValueAnimator anim = new ValueAnimator();
        anim.setIntValues(values);
        return anim;
    
public static android.animation.ValueAnimatorofObject(TypeEvaluator evaluator, java.lang.Object values)
Constructs and returns a ValueAnimator that animates between Object values. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

Since ValueAnimator does not know how to animate between arbitrary Objects, this factory method also takes a TypeEvaluator object that the ValueAnimator will use to perform that interpolation.

param
evaluator A TypeEvaluator that will be called on each animation frame to provide the ncessry interpolation between the Object values to derive the animated value.
param
values A set of values that the animation will animate between over time.
return
A ValueAnimator object that is set up to animate between the given values.

        ValueAnimator anim = new ValueAnimator();
        anim.setObjectValues(values);
        anim.setEvaluator(evaluator);
        return anim;
    
public static android.animation.ValueAnimatorofPropertyValuesHolder(PropertyValuesHolder values)
Constructs and returns a ValueAnimator that animates between the values specified in the PropertyValuesHolder objects.

param
values A set of PropertyValuesHolder objects whose values will be animated between over time.
return
A ValueAnimator object that is set up to animate between the given values.

        ValueAnimator anim = new ValueAnimator();
        anim.setValues(values);
        return anim;
    
public voidpause()

        boolean previouslyPaused = mPaused;
        super.pause();
        if (!previouslyPaused && mPaused) {
            mPauseTime = -1;
            mResumed = false;
        }
    
public voidremoveAllUpdateListeners()
Removes all listeners from the set listening to frame updates for this animation.

        if (mUpdateListeners == null) {
            return;
        }
        mUpdateListeners.clear();
        mUpdateListeners = null;
    
public voidremoveUpdateListener(android.animation.ValueAnimator$AnimatorUpdateListener listener)
Removes a listener from the set listening to frame updates for this animation.

param
listener the listener to be removed from the current set of update listeners for this animation.

        if (mUpdateListeners == null) {
            return;
        }
        mUpdateListeners.remove(listener);
        if (mUpdateListeners.size() == 0) {
            mUpdateListeners = null;
        }
    
public voidresume()

        if (mPaused) {
            mResumed = true;
        }
        super.resume();
    
public voidreverse()
Plays the ValueAnimator in reverse. If the animation is already running, it will stop itself and play backwards from the point reached when reverse was called. If the animation is not currently running, then it will start from the end and play backwards. This behavior is only set for the current animation; future playing of the animation will use the default behavior of playing forward.

        mPlayingBackwards = !mPlayingBackwards;
        if (mPlayingState == RUNNING) {
            long currentTime = AnimationUtils.currentAnimationTimeMillis();
            long currentPlayTime = currentTime - mStartTime;
            long timeLeft = mDuration - currentPlayTime;
            mStartTime = currentTime - timeLeft;
            mReversing = !mReversing;
        } else if (mStarted) {
            end();
        } else {
            start(true);
        }
    
public voidsetAllowRunningAsynchronously(boolean mayRunAsync)

Whether or not the ValueAnimator is allowed to run asynchronously off of the UI thread. This is a hint that informs the ValueAnimator that it is OK to run the animation off-thread, however ValueAnimator may decide that it must run the animation on the UI thread anyway. For example if there is an {@link AnimatorUpdateListener} the animation will run on the UI thread, regardless of the value of this hint.

Regardless of whether or not the animation runs asynchronously, all listener callbacks will be called on the UI thread.

To be able to use this hint the following must be true:

  1. {@link #getAnimatedFraction()} is not needed (it will return undefined values).
  2. The animator is immutable while {@link #isStarted()} is true. Requests to change values, duration, delay, etc... may be ignored.
  3. Lifecycle callback events may be asynchronous. Events such as {@link Animator.AnimatorListener#onAnimationEnd(Animator)} or {@link Animator.AnimatorListener#onAnimationRepeat(Animator)} may end up delayed as they must be posted back to the UI thread, and any actions performed by those callbacks (such as starting new animations) will not happen in the same frame.
  4. State change requests ({@link #cancel()}, {@link #end()}, {@link #reverse()}, etc...) may be asynchronous. It is guaranteed that all state changes that are performed on the UI thread in the same frame will be applied as a single atomic update, however that frame may be the current frame, the next frame, or some future frame. This will also impact the observed state of the Animator. For example, {@link #isStarted()} may still return true after a call to {@link #end()}. Using the lifecycle callbacks is preferred over queries to {@link #isStarted()}, {@link #isRunning()}, and {@link #isPaused()} for this reason.

hide

        // It is up to subclasses to support this, if they can.
    
public voidsetCurrentFraction(float fraction)
Sets the position of the animation to the specified fraction. This fraction should be between 0 and the total fraction of the animation, including any repetition. That is, a fraction of 0 will position the animation at the beginning, a value of 1 at the end, and a value of 2 at the end of a reversing animator that repeats once. If the animation has not yet been started, then it will not advance forward after it is set to this fraction; it will simply set the fraction to this value and perform any appropriate actions based on that fraction. If the animation is already running, then setCurrentFraction() will set the current fraction to this value and continue playing from that point. {@link Animator.AnimatorListener} events are not called due to changing the fraction; those events are only processed while the animation is running.

param
fraction The fraction to which the animation is advanced or rewound. Values outside the range of 0 to the maximum fraction for the animator will be clamped to the correct range.

        initAnimation();
        if (fraction < 0) {
            fraction = 0;
        }
        int iteration = (int) fraction;
        if (fraction == 1) {
            iteration -= 1;
        } else if (fraction > 1) {
            if (iteration < (mRepeatCount + 1) || mRepeatCount == INFINITE) {
                if (mRepeatMode == REVERSE) {
                    mPlayingBackwards = (iteration % 2) != 0;
                }
                fraction = fraction % 1f;
            } else {
                fraction = 1;
                iteration -= 1;
            }
        } else {
            mPlayingBackwards = mReversing;
        }
        mCurrentIteration = iteration;
        long seekTime = (long) (mDuration * fraction);
        long currentTime = AnimationUtils.currentAnimationTimeMillis();
        mStartTime = currentTime - seekTime;
        if (mPlayingState != RUNNING) {
            mSeekFraction = fraction;
            mPlayingState = SEEKED;
        }
        if (mPlayingBackwards) {
            fraction = 1f - fraction;
        }
        animateValue(fraction);
    
public voidsetCurrentPlayTime(long playTime)
Sets the position of the animation to the specified point in time. This time should be between 0 and the total duration of the animation, including any repetition. If the animation has not yet been started, then it will not advance forward after it is set to this time; it will simply set the time to this value and perform any appropriate actions based on that time. If the animation is already running, then setCurrentPlayTime() will set the current playing time to this value and continue playing from that point.

param
playTime The time, in milliseconds, to which the animation is advanced or rewound.

        float fraction = mUnscaledDuration > 0 ? (float) playTime / mUnscaledDuration : 1;
        setCurrentFraction(fraction);
    
public android.animation.ValueAnimatorsetDuration(long duration)
Sets the length of the animation. The default duration is 300 milliseconds.

param
duration The length of the animation, in milliseconds. This value cannot be negative.
return
ValueAnimator The object called with setDuration(). This return value makes it easier to compose statements together that construct and then set the duration, as in ValueAnimator.ofInt(0, 10).setDuration(500).start().

        if (duration < 0) {
            throw new IllegalArgumentException("Animators cannot have negative duration: " +
                    duration);
        }
        mUnscaledDuration = duration;
        updateScaledDuration();
        return this;
    
public static voidsetDurationScale(float durationScale)

hide



          
         
        sDurationScale = durationScale;
    
public voidsetEvaluator(TypeEvaluator value)
The type evaluator to be used when calculating the animated values of this animation. The system will automatically assign a float or int evaluator based on the type of startValue and endValue in the constructor. But if these values are not one of these primitive types, or if different evaluation is desired (such as is necessary with int values that represent colors), a custom evaluator needs to be assigned. For example, when running an animation on color values, the {@link ArgbEvaluator} should be used to get correct RGB color interpolation.

If this ValueAnimator has only one set of values being animated between, this evaluator will be used for that set. If there are several sets of values being animated, which is the case if PropertyValuesHolder objects were set on the ValueAnimator, then the evaluator is assigned just to the first PropertyValuesHolder object.

param
value the evaluator to be used this animation

        if (value != null && mValues != null && mValues.length > 0) {
            mValues[0].setEvaluator(value);
        }
    
public voidsetFloatValues(float values)
Sets float values that will be animated between. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

If there are already multiple sets of values defined for this ValueAnimator via more than one PropertyValuesHolder object, this method will set the values for the first of those objects.

param
values A set of values that the animation will animate between over time.

        if (values == null || values.length == 0) {
            return;
        }
        if (mValues == null || mValues.length == 0) {
            setValues(PropertyValuesHolder.ofFloat("", values));
        } else {
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setFloatValues(values);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    
public static voidsetFrameDelay(long frameDelay)
The amount of time, in milliseconds, between each frame of the animation. This is a requested time that the animation will attempt to honor, but the actual delay between frames may be different, depending on system load and capabilities. This is a static function because the same delay will be applied to all animations, since they are all run off of a single timing loop. The frame delay may be ignored when the animation system uses an external timing source, such as the display refresh rate (vsync), to govern animations.

param
frameDelay the requested time between frames, in milliseconds

        Choreographer.setFrameDelay(frameDelay);
    
public voidsetIntValues(int values)
Sets int values that will be animated between. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

If there are already multiple sets of values defined for this ValueAnimator via more than one PropertyValuesHolder object, this method will set the values for the first of those objects.

param
values A set of values that the animation will animate between over time.

        if (values == null || values.length == 0) {
            return;
        }
        if (mValues == null || mValues.length == 0) {
            setValues(PropertyValuesHolder.ofInt("", values));
        } else {
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setIntValues(values);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    
public voidsetInterpolator(TimeInterpolator value)
The time interpolator used in calculating the elapsed fraction of this animation. The interpolator determines whether the animation runs with linear or non-linear motion, such as acceleration and deceleration. The default value is {@link android.view.animation.AccelerateDecelerateInterpolator}

param
value the interpolator to be used by this animation. A value of null will result in linear interpolation.

        if (value != null) {
            mInterpolator = value;
        } else {
            mInterpolator = new LinearInterpolator();
        }
    
public voidsetObjectValues(java.lang.Object values)
Sets the values to animate between for this animation. A single value implies that that value is the one being animated to. However, this is not typically useful in a ValueAnimator object because there is no way for the object to determine the starting value for the animation (unlike ObjectAnimator, which can derive that value from the target object and property being animated). Therefore, there should typically be two or more values.

If there are already multiple sets of values defined for this ValueAnimator via more than one PropertyValuesHolder object, this method will set the values for the first of those objects.

There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate between these value objects. ValueAnimator only knows how to interpolate between the primitive types specified in the other setValues() methods.

param
values The set of values to animate between.

        if (values == null || values.length == 0) {
            return;
        }
        if (mValues == null || mValues.length == 0) {
            setValues(PropertyValuesHolder.ofObject("", null, values));
        } else {
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setObjectValues(values);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    
public voidsetRepeatCount(int value)
Sets how many times the animation should be repeated. If the repeat count is 0, the animation is never repeated. If the repeat count is greater than 0 or {@link #INFINITE}, the repeat mode will be taken into account. The repeat count is 0 by default.

param
value the number of times the animation should be repeated

        mRepeatCount = value;
    
public voidsetRepeatMode(int value)
Defines what this animation should do when it reaches the end. This setting is applied only when the repeat count is either greater than 0 or {@link #INFINITE}. Defaults to {@link #RESTART}.

param
value {@link #RESTART} or {@link #REVERSE}

        mRepeatMode = value;
    
public voidsetStartDelay(long startDelay)
The amount of time, in milliseconds, to delay starting the animation after {@link #start()} is called.

param
startDelay The amount of the delay, in milliseconds

        this.mStartDelay = (long)(startDelay * sDurationScale);
        mUnscaledStartDelay = startDelay;
    
public voidsetValues(PropertyValuesHolder values)
Sets the values, per property, being animated between. This function is called internally by the constructors of ValueAnimator that take a list of values. But a ValueAnimator can be constructed without values and this method can be called to set the values manually instead.

param
values The set of values, per property, being animated between.

        int numValues = values.length;
        mValues = values;
        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
        for (int i = 0; i < numValues; ++i) {
            PropertyValuesHolder valuesHolder = values[i];
            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    
private voidstart(boolean playBackwards)
Start the animation playing. This version of start() takes a boolean flag that indicates whether the animation should play in reverse. The flag is usually false, but may be set to true if called from the reverse() method.

The animation started by calling this method will be run on the thread that called this method. This thread should have a Looper on it (a runtime exception will be thrown if this is not the case). Also, if the animation will animate properties of objects in the view hierarchy, then the calling thread should be the UI thread for that view hierarchy.

param
playBackwards Whether the ValueAnimator should start playing in reverse.

        if (Looper.myLooper() == null) {
            throw new AndroidRuntimeException("Animators may only be run on Looper threads");
        }
        mReversing = playBackwards;
        mPlayingBackwards = playBackwards;
        if (playBackwards && mSeekFraction != -1) {
            if (mSeekFraction == 0 && mCurrentIteration == 0) {
                // special case: reversing from seek-to-0 should act as if not seeked at all
                mSeekFraction = 0;
            } else if (mRepeatCount == INFINITE) {
                mSeekFraction = 1 - (mSeekFraction % 1);
            } else {
                mSeekFraction = 1 + mRepeatCount - (mCurrentIteration + mSeekFraction);
            }
            mCurrentIteration = (int) mSeekFraction;
            mSeekFraction = mSeekFraction % 1;
        }
        if (mCurrentIteration > 0 && mRepeatMode == REVERSE &&
                (mCurrentIteration < (mRepeatCount + 1) || mRepeatCount == INFINITE)) {
            // if we were seeked to some other iteration in a reversing animator,
            // figure out the correct direction to start playing based on the iteration
            if (playBackwards) {
                mPlayingBackwards = (mCurrentIteration % 2) == 0;
            } else {
                mPlayingBackwards = (mCurrentIteration % 2) != 0;
            }
        }
        int prevPlayingState = mPlayingState;
        mPlayingState = STOPPED;
        mStarted = true;
        mStartedDelay = false;
        mPaused = false;
        updateScaledDuration(); // in case the scale factor has changed since creation time
        AnimationHandler animationHandler = getOrCreateAnimationHandler();
        animationHandler.mPendingAnimations.add(this);
        if (mStartDelay == 0) {
            // This sets the initial value of the animation, prior to actually starting it running
            if (prevPlayingState != SEEKED) {
                setCurrentPlayTime(0);
            }
            mPlayingState = STOPPED;
            mRunning = true;
            notifyStartListeners();
        }
        animationHandler.start();
    
public voidstart()

        start(false);
    
private voidstartAnimation(android.animation.ValueAnimator$AnimationHandler handler)
Called internally to start an animation by adding it to the active animations list. Must be called on the UI thread.

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
                    System.identityHashCode(this));
        }
        initAnimation();
        handler.mAnimations.add(this);
        if (mStartDelay > 0 && mListeners != null) {
            // Listeners were already notified in start() if startDelay is 0; this is
            // just for delayed animations
            notifyStartListeners();
        }
    
public java.lang.StringtoString()

        String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode());
        if (mValues != null) {
            for (int i = 0; i < mValues.length; ++i) {
                returnVal += "\n    " + mValues[i].toString();
            }
        }
        return returnVal;
    
private voidupdateScaledDuration()

        mDuration = (long)(mUnscaledDuration * sDurationScale);