Fields Summary |
---|
private static float | sDurationScaleInternal constants |
static final int | STOPPEDValues used with internal variable mPlayingState to indicate the current state of an
animation. |
static final int | RUNNING |
static final int | SEEKED |
long | mStartTimeInternal 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 | mSeekFractionSet when setCurrentPlayTime() is called. If negative, animation is not currently seeked
to a value. |
private long | mPauseTimeSet 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 | mResumedSet 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 | mPlayingBackwardsUsed 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 | mReversingFlag 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 | mCurrentIterationThis variable tracks the current iteration that is playing. When mCurrentIteration exceeds the
repeatCount (if repeatCount!=INFINITE), the animation ends |
private float | mCurrentFractionTracks current elapsed/eased fraction, for querying in getAnimatedFraction(). |
private boolean | mStartedDelayTracks whether a startDelay'd animation has begun playing through the startDelay. |
private long | mDelayStartTimeTracks 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 | mPlayingStateFlag 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 | mRunningAdditional 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 | mStartedAdditional playing state to indicate whether an animator has been start()'d, whether or
not there is a nonzero startDelay. |
private boolean | mStartListenersCalledTracks 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 | mInitializedFlag 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 | mRepeatModeThe 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 | mInterpolatorThe 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 | mUpdateListenersThe set of listeners to be sent events through the life of an animation. |
PropertyValuesHolder[] | mValuesThe property/value sets being animated. |
HashMap | mValuesMapA 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 | RESTARTWhen the animation reaches the end and repeatCount is INFINITE
or a positive value, the animation restarts from the beginning. |
public static final int | REVERSEWhen the animation reaches the end and repeatCount is INFINITE
or a positive value, the animation reverses direction on every iteration. |
public static final int | INFINITEThis value used used with the {@link #setRepeatCount(int)} property to repeat
the animation indefinitely. |
Methods Summary |
---|
public void | addUpdateListener(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.
if (mUpdateListeners == null) {
mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
}
mUpdateListeners.add(listener);
|
void | animateValue(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.
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);
}
}
|
boolean | animationFrame(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).
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 boolean | canReverse()
return true;
|
public void | cancel()
// 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 void | clearAllAnimations()Clear all animations on this thread, without canceling or ending them.
This should be used with caution.
AnimationHandler handler = sAnimationHandler.get();
if (handler != null) {
handler.mAnimations.clear();
handler.mPendingAnimations.clear();
handler.mDelayedAnims.clear();
}
|
public android.animation.ValueAnimator | clone()
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 boolean | delayedAnimationFrame(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.
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 boolean | doAnimationFrame(long frameTime)Processes a frame of the animation, adjusting the start time if needed.
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 void | end()
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 void | endAnimation(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.
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 float | getAnimatedFraction()Returns the current animation fraction, which is the elapsed/interpolated fraction used in
the most recent frame update on the animation.
return mCurrentFraction;
|
public java.lang.Object | getAnimatedValue()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.
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.Object | getAnimatedValue(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.
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 int | getCurrentAnimationsCount()Return the number of animations currently running.
Used by StrictMode internally to annotate violations.
May be called on arbitrary threads!
AnimationHandler handler = sAnimationHandler.get();
return handler != null ? handler.mAnimations.size() : 0;
|
public long | getCurrentPlayTime()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.
if (!mInitialized || mPlayingState == STOPPED) {
return 0;
}
return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
|
public long | getDuration()Gets the length of the animation. The default duration is 300 milliseconds.
return mUnscaledDuration;
|
public static float | getDurationScale()
return sDurationScale;
|
public static long | getFrameDelay()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 Choreographer.getFrameDelay();
|
public TimeInterpolator | getInterpolator()Returns the timing interpolator that this ValueAnimator uses.
return mInterpolator;
|
java.lang.String | getNameForTrace()Returns the name of this animator for debugging purposes.
return "animator";
|
private static android.animation.ValueAnimator$AnimationHandler | getOrCreateAnimationHandler()
AnimationHandler handler = sAnimationHandler.get();
if (handler == null) {
handler = new AnimationHandler();
sAnimationHandler.set(handler);
}
return handler;
|
public int | getRepeatCount()Defines how many times the animation should repeat. The default value
is 0.
return mRepeatCount;
|
public int | getRepeatMode()Defines what this animation should do when it reaches the end.
return mRepeatMode;
|
public long | getStartDelay()The amount of time, in milliseconds, to delay starting the animation after
{@link #start()} is called.
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 mValues;
|
void | initAnimation()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 boolean | isRunning()
return (mPlayingState == RUNNING || mRunning);
|
public boolean | isStarted()
return mStarted;
|
private void | notifyStartListeners()
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.ValueAnimator | ofArgb(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.
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
anim.setEvaluator(ArgbEvaluator.getInstance());
return anim;
|
public static android.animation.ValueAnimator | ofFloat(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.
ValueAnimator anim = new ValueAnimator();
anim.setFloatValues(values);
return anim;
|
public static android.animation.ValueAnimator | ofInt(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.
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
|
public static android.animation.ValueAnimator | ofObject(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.
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
|
public static android.animation.ValueAnimator | ofPropertyValuesHolder(PropertyValuesHolder values)Constructs and returns a ValueAnimator that animates between the values
specified in the PropertyValuesHolder objects.
ValueAnimator anim = new ValueAnimator();
anim.setValues(values);
return anim;
|
public void | pause()
boolean previouslyPaused = mPaused;
super.pause();
if (!previouslyPaused && mPaused) {
mPauseTime = -1;
mResumed = false;
}
|
public void | removeAllUpdateListeners()Removes all listeners from the set listening to frame updates for this animation.
if (mUpdateListeners == null) {
return;
}
mUpdateListeners.clear();
mUpdateListeners = null;
|
public void | removeUpdateListener(android.animation.ValueAnimator$AnimatorUpdateListener listener)Removes a listener from the set listening to frame updates for this animation.
if (mUpdateListeners == null) {
return;
}
mUpdateListeners.remove(listener);
if (mUpdateListeners.size() == 0) {
mUpdateListeners = null;
}
|
public void | resume()
if (mPaused) {
mResumed = true;
}
super.resume();
|
public void | reverse()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 void | setAllowRunningAsynchronously(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:
- {@link #getAnimatedFraction()} is not needed (it will return undefined values).
- The animator is immutable while {@link #isStarted()} is true. Requests
to change values, duration, delay, etc... may be ignored.
- 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.
- 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.
// It is up to subclasses to support this, if they can.
|
public void | setCurrentFraction(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.
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 void | setCurrentPlayTime(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.
float fraction = mUnscaledDuration > 0 ? (float) playTime / mUnscaledDuration : 1;
setCurrentFraction(fraction);
|
public android.animation.ValueAnimator | setDuration(long duration)Sets the length of the animation. The default duration is 300 milliseconds.
if (duration < 0) {
throw new IllegalArgumentException("Animators cannot have negative duration: " +
duration);
}
mUnscaledDuration = duration;
updateScaledDuration();
return this;
|
public static void | setDurationScale(float durationScale)
sDurationScale = durationScale;
|
public void | setEvaluator(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.
if (value != null && mValues != null && mValues.length > 0) {
mValues[0].setEvaluator(value);
}
|
public void | setFloatValues(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.
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 void | setFrameDelay(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.
Choreographer.setFrameDelay(frameDelay);
|
public void | setIntValues(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.
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 void | setInterpolator(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}
if (value != null) {
mInterpolator = value;
} else {
mInterpolator = new LinearInterpolator();
}
|
public void | setObjectValues(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.
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 void | setRepeatCount(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.
mRepeatCount = value;
|
public void | setRepeatMode(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}.
mRepeatMode = value;
|
public void | setStartDelay(long startDelay)The amount of time, in milliseconds, to delay starting the animation after
{@link #start()} is called.
this.mStartDelay = (long)(startDelay * sDurationScale);
mUnscaledStartDelay = startDelay;
|
public void | setValues(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.
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 void | start(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.
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 void | start()
start(false);
|
private void | startAnimation(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.String | toString()
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 void | updateScaledDuration()
mDuration = (long)(mUnscaledDuration * sDurationScale);
|