@ThreadSafe @ReferenceObject @RegionLock(value="AnimatorLock is this protects AnimatorState") @TrackPartiallyInitialized public final class Animator extends java.lang.Object implements TimingSource.TickListener
Animator.Builder
instance by invoking various set methods control the
parameters under which the desired animation is run. The parameters of this
class use the concepts of a "cycle" (the base animation) and an "envelope"
that controls how the cycle is started, ended, and repeated.
For example, this animation will run for 1 second, calling your
TimingTarget
, myTarget
, with timing events when the animation
is started, running, and stopped:
Animator.setDefaultTimingSource(source); // shared timing source Animator animator = new Animator.Builder().setDuration(1, TimeUnit.SECONDS).addTarget(myTarget).build(); animator.start();The following variation will run a half-second animation 4 times, reversing direction each time:
Animator animator = new Animator.Builder().setDuration(500, TimeUnit.MILLISECONDS).setRepeatCount(4).addTarget(myTarget).build(); animator.start();More complex animations can be created through the use of the complete set of properties in
Animator.Builder
.
This class provides a useful "debug" name via
Animator.Builder.setDebugName(String)
and getDebugName()
. The debug
name is also output by toString()
. This feature is intended to aid
debugging.
Instances can be started again after they complete, however, ensure that they
are not running, via !isRunning()
or await()
,
before start()
or startReverse()
is called. Even if you
successfully invoked stop()
or cancel()
it can take some
time for all the calls to registered TimingTarget
s to complete. Use
of await()
is far more efficient than polling the state of the
animation with isRunning()
. However, do not call await()
in
the thread context of the timing source for this animation or it will block
forever.
This class is thread-safe. Synchronizing on the instance(this) may be used to protect state changes over several calls.
Animator.Builder
Modifier and Type | Class and Description |
---|---|
static class |
Animator.Builder
This class is used to construct
Animator instances. |
static class |
Animator.Direction
Direction is used to set the initial direction in which the animation
starts.
|
static class |
Animator.EndBehavior
EndBehavior determines what happens at the end of the animation.
|
static class |
Animator.RepeatBehavior
RepeatBehavior determines how each successive cycle will flow.
|
Modifier and Type | Field and Description |
---|---|
static long |
INFINITE
Used to specify unending repeat count.
|
Modifier and Type | Method and Description |
---|---|
void |
addTarget(TimingTarget target)
Adds a
TimingTarget to the list of targets that get notified of
each timing event while the animation is running. |
void |
addTargets(java.util.Collection<TimingTarget> targets)
Adds the collection of passed
TimingTarget s to the list of targets
that get notified of each timing event while the animation is running. |
void |
addTargets(TimingTarget... targets)
Adds the collection of passed
TimingTarget s to the list of targets
that get notified of each timing event while the animation is running. |
void |
await()
|
boolean |
cancel()
This method is like the
stop() method, only this one will not result
in a calls to the TimingTarget.end(Animator) method of all the
registered timing targets of this animation; it simply stops the animation
immediately and returns. |
void |
cancelAndAwait()
A convenience method that is equivalent to the code below.
|
void |
clearTargets()
Removes all of the elements from from the list of targets that get notified
of each timing event while the animation is running.
|
Animator.Direction |
getCurrentDirection()
Returns the current direction of the animation.
|
long |
getCycleElapsedTime()
Returns the elapsed time in nanoseconds for the current animation
cycle.Uses
System.nanoTime() to get the current time. |
long |
getCycleElapsedTime(long currentTimeNanos)
Returns the elapsed time in nanoseconds for the current animation cycle
from the passed time.
|
java.lang.String |
getDebugName()
Gets the "debug" name of this animation.
|
static TimingSource |
getDefaultTimingSource()
Gets the timing source being used as the default for the construction on
animations.
|
boolean |
getDisposeTimingSource()
Gets if this animation will invoke
TimingSource.dispose() on its
timing source when it ends. |
long |
getDuration()
Gets the duration of one cycle of this animation.
|
java.util.concurrent.TimeUnit |
getDurationTimeUnit()
Gets the time unit of the duration of one cycle of this animation.
|
Animator.EndBehavior |
getEndBehavior()
Gets the behavior at the end of this animation.
|
Interpolator |
getInterpolator()
Gets the interpolator for this animation.
|
Animator.RepeatBehavior |
getRepeatBehavior()
Gets the repeat behavior of this animation.
|
long |
getRepeatCount()
Gets the number of times the animation cycle will repeat.
|
long |
getStartDelay()
Gets the start delay of this animation.
|
java.util.concurrent.TimeUnit |
getStartDelayTimeUnit()
Gets the time unit of the start delay of this animation.
|
Animator.Direction |
getStartDirection()
Gets the start direction for the initial animation cycle.
|
java.util.ArrayList<TimingTarget> |
getTargets()
Gets the list of
TimingTarget s that get notified of each timing
event while the animation is running. |
TimingSource |
getTimingSource()
Gets the timing source for this animation.
|
long |
getTotalElapsedTime()
Returns the total elapsed time in nanoseconds for the current animation.
|
long |
getTotalElapsedTime(long currentTimeNanos)
Returns the total elapsed time in nanoseconds for the current animation
from the passed time.
|
boolean |
isPaused()
Returns whether this animation is currently running — but paused.
|
boolean |
isRunning()
Returns whether this has been started and has not yet completed.
|
void |
pause()
This method pauses a running animation.
|
void |
removeTarget(TimingTarget target)
Removes the specified
TimingTarget from the list of targets that
get notified of each timing event while the animation is running. |
void |
removeTargets(java.util.Collection<TimingTarget> targets)
Removes the specified collection of
TimingTarget s from the list of
targets that get notified of each timing event while the animation is
running. |
void |
removeTargets(TimingTarget... targets)
Removes the specified collection of
TimingTarget s from the list of
targets that get notified of each timing event while the animation is
running. |
void |
restart()
Restarts the animation.
|
void |
restartReverse()
Restarts the animation in the reverse direction.
|
void |
resume()
This method resumes a paused animation.
|
boolean |
reverseNow()
Reverses the direction of the animation if it is running and is not paused
or stopping.
|
static void |
setDefaultTimingSource(TimingSource timingSource)
Sets the passed timing source as the default used for the construction of
animations.
|
void |
start()
Starts the animation.
|
void |
startReverse()
Starts the animation in the reverse direction.
|
boolean |
stop()
Clients may invoke this method to stop a running animation, however, most
animations will stop on their own.
|
void |
stopAndAwait()
A convenience method that is equivalent to the code below.
|
void |
timingSourceTick(TimingSource source,
long nanoTime)
Not intended for use by client code.
|
java.lang.String |
toString() |
public static void setDefaultTimingSource(@Nullable TimingSource timingSource)
Animator.Builder
uses
the default timing source set by this method.
Passing null
to this method clears the default timing source.
The client code remains responsible for disposing of the timing source when it is finished using it.
timingSource
- a timing source or null
to clear the default.@Nullable public static TimingSource getDefaultTimingSource()
Animator.Builder
uses
the default timing source. A null
result indicates that no default
timing source has been set.null
if none.@Nullable @RegionEffects(value="reads Instance") public java.lang.String getDebugName()
null
.@RegionEffects(value="reads Instance") public long getDuration()
getDurationTimeUnit()
.INFINITE
, meaning the animation will run until
manually stopped.getDurationTimeUnit()
@NonNull @RegionEffects(value="reads Instance") public java.util.concurrent.TimeUnit getDurationTimeUnit()
getDuration()
.getDuration()
@NonNull @RegionEffects(value="reads Instance") public Animator.EndBehavior getEndBehavior()
@NonNull public Interpolator getInterpolator()
@NonNull @RegionEffects(value="reads Instance") public Animator.RepeatBehavior getRepeatBehavior()
@RegionEffects(value="reads Instance") public long getRepeatCount()
INFINITE
for animations that repeat
indefinitely.@NonNull @RegionEffects(value="reads Instance") public Animator.Direction getStartDirection()
@RegionEffects(value="reads Instance") public long getStartDelay()
start()
or
startReverse()
. The units of this value are obtained by
calling getStartDelayTimeUnit()
.getStartDelayTimeUnit()
@NonNull @RegionEffects(value="reads Instance") public java.util.concurrent.TimeUnit getStartDelayTimeUnit()
start()
or startReverse()
. The duration is
obtained by calling getStartDelay()
.getStartDelay()
@NonNull @RegionEffects(value="reads Instance") public TimingSource getTimingSource()
@RegionEffects(value="reads Instance") public boolean getDisposeTimingSource()
TimingSource.dispose()
on its
timing source when it ends.true
if the animation will invoke
TimingSource.dispose()
on its timing source when it ends,
false
if not.public void addTarget(TimingTarget target)
TimingTarget
to the list of targets that get notified of
each timing event while the animation is running.
This can be done at any time before, during, or after the animation has started or completed; the new target will begin having its methods called as soon as it is added.
TimingTarget
s will be called in the order they are added. Duplicate
additions are ignored.
target
- a TimingTarget
object.public void addTargets(java.util.Collection<TimingTarget> targets)
TimingTarget
s to the list of targets
that get notified of each timing event while the animation is running.
This can be done at any time before, during, or after the animation has started or completed; the new target will begin having its methods called as soon as it is added.
TimingTarget
s will be called in the order they are added. Duplicate
additions are ignored.
targets
- a collection of TimingTarget
objects.public void addTargets(TimingTarget... targets)
TimingTarget
s to the list of targets
that get notified of each timing event while the animation is running.
This can be done at any time before, during, or after the animation has started or completed; the new target will begin having its methods called as soon as it is added.
TimingTarget
s will be called in the order they are added. Duplicate
additions are ignored.
targets
- a collection of TimingTarget
objects.public void removeTarget(TimingTarget target)
TimingTarget
from the list of targets that
get notified of each timing event while the animation is running.
This can be done at any time before, during, or after the animation has started or completed; the target will cease having its methods called as soon as it is removed.
target
- a TimingTarget
object.public void removeTargets(java.util.Collection<TimingTarget> targets)
TimingTarget
s from the list of
targets that get notified of each timing event while the animation is
running.
This can be done at any time before, during, or after the animation has started or completed; the target will cease having its methods called as soon as it is removed.
targets
- a collection of TimingTarget
objects.public void removeTargets(TimingTarget... targets)
TimingTarget
s from the list of
targets that get notified of each timing event while the animation is
running.
This can be done at any time before, during, or after the animation has started or completed; the target will cease having its methods called as soon as it is removed.
targets
- a collection of TimingTarget
objects.public java.util.ArrayList<TimingTarget> getTargets()
TimingTarget
s that get notified of each timing
event while the animation is running.
The returned list is a copy and can be mutated freely.
TimingTarget
s of this animation.public void clearTargets()
The set of registered TimingTarget
objects will be empty after this
call returns.
public void start()
java.lang.IllegalStateException
- if animation is already running; this command may only be run
prior to starting the animation or after the animation has ended.public void restart()
start()
.
This call does not block.
Shutdown callbacks to any registered TimingTarget
instances are
made at the next tick of this animation's timing source, after that time
the animation actually restarts. Therefore it is possible to call
restart()
or restartReverse()
multiple times but only get
the effect of a single restart. If this is done then only the first call
takes effect, any others are ignored.
public void startReverse()
java.lang.IllegalStateException
- if animation is already running; this command may only be run
prior to starting the animation or after the animation has ended.public void restartReverse()
startReverse()
.
This call does not block.
Shutdown callbacks to any registered TimingTarget
instances are
made at the next tick of this animation's timing source, after that time
the animation actually restarts. Therefore it is possible to call
restart()
or restartReverse()
multiple times but only get
the effect of a single restart. If this is done then only the first call
takes effect, any others are ignored.
@RegionEffects(value="reads Instance") public boolean isRunning()
start()
or startReverse()
and when it (a) completes normally, (b)
stop()
is called on it and all callbacks to registered
TimingTarget
s have completed, or (c) cancel()
is called on
it.
A paused animation is still considered to be running.
true
if the animation is running, false
if it is
not.@NonNull @RegionEffects(value="reads Instance") public Animator.Direction getCurrentDirection()
public boolean stop()
false
.
This call does not block.
This call will result in calls to the TimingTarget.end(Animator)
method of all the registered timing targets of this animation.
The animation takes some period of time to actually stop. The stop started
by this call finishes upon the next tick of this animation's timing source.
What happens is that TimingTarget.end(Animator)
callbacks to any
registered TimingTarget
instances are made at the next tick of this
animation's timing source. This is done to ensure all callbacks are made in
the thread context of this animation's timing target. This means that the
code snippet "a.stop(); a.start();
" could fail throwing an
IllegalStateException
at the call to start()
because the
animation is not immediately ready to be started again. If you are trying
to wait for the animation to stop so that it can be restarted, then you
should use restart()
or restartReverse()
which are safe
to call in the thread context of this animation's timing source.
true
if the animation was running and was successfully
stopped, false
if the animation was not running or was in
the process of stopping and didn't need to be stopped.cancel()
public void stopAndAwait()
a.stop(); try { a.await(); } catch (InterruptedException ignore) { }
a
is the animator this method is invoked on.
This is a blocking call.
Never invoke this method within the thread context of this animation's
timing source—doing so will cause this call to block forever. If
you are trying to wait for the animation to stop so that it can be
restarted, then you should use restart()
or
restartReverse()
which are safe to call in the thread context of
this animation's timing source.
This method is primarily intended for testing.
public boolean cancel()
stop()
method, only this one will not result
in a calls to the TimingTarget.end(Animator)
method of all the
registered timing targets of this animation; it simply stops the animation
immediately and returns. If the animation is not running, or is stopping,
then this method returns false
.
This call does not block.
The animation may take some period of time to actually cancel. The cancel
started by this call finishes upon the next tick of this animation's timing
source. This means that the code snippet "a.cancel(); a.start();
"
could fail throwing an IllegalStateException
at the call to
start()
because the animation is not immediately ready to be
started again. If you are trying to wait for the animation to stop so that
it can be restarted, then you should use restart()
or
restartReverse()
which are safe to call in the thread context of
this animation's timing source.
true
if the animation was running and was successfully
stopped, false
if the animation was not running or was in
the process of stopping and didn't need to be stopped.stop()
public void cancelAndAwait()
a.cancel(); try { a.await(); } catch (InterruptedException ignore) { }
a
is the animator this method is invoked on.
This is a blocking call. Never invoke this method within the thread context of this animation's timing source—doing so will cause this call to block forever.
This method is primarily intended for testing.
public void pause()
resume()
method.
Pausing a non-running, stopping, or already paused animation has no effect.
resume()
,
isRunning()
,
isPaused()
public boolean isPaused()
false
is returned.true
if the animation is currently running — but
paused, false
otherwise.public void resume()
pause()
public boolean reverseNow()
false
.
The actual reverse occurs at the next tick of this animation's
TimingSource
. All calls are remembered, however, so no successful
reversals are lost.
true
if the animation was successfully reversed,
false
if the attempt to reverse the animation failed.public void await() throws java.lang.InterruptedException
stop()
or cancel()
, unless
the thread is interrupted. All callbacks to
registered TimingTarget
s have been completed when this method
returns (unless, as noted above, the thread is
interrupted).
If the animation is not running then this method returns immediately, otherwise this is a blocking call.
Never invoke this method within the thread context of this animation's
timing source—doing so will cause this call to block forever. If
you are trying to wait for the animation to stop so that it can be
restarted, then you should use restart()
or
restartReverse()
which are safe to call in the thread context of
this animation's timing source.
If the current thread:
InterruptedException
is thrown and the current thread's
interrupted status is cleared.
This method is primarily intended for testing.
java.lang.InterruptedException
- if the current thread is interrupted while waiting.public long getCycleElapsedTime()
System.nanoTime()
to get the current time.
If a start delay is set on this animation, then it is possible that the value returned from this method will be negative. This situation occurs when the animation has been started but is waiting for the start delay to elapse.
@RegionEffects(value="reads Instance") public long getCycleElapsedTime(long currentTimeNanos)
If a start delay is set on this animation, then it is possible that the value returned from this method will be negative. This situation occurs when the animation has been started but is waiting for the start delay to elapse.
currentTimeNanos
- value of current time, from System.nanoTime()
, to use in
calculating the elapsed time.public long getTotalElapsedTime()
System.nanoTime()
to get the current time.
This value does not consider any start delay, it simple returns the time elapsed from when the animation was started until now.
@RegionEffects(value="reads Instance") public long getTotalElapsedTime(long currentTimeNanos)
This value does not consider any start delay, it simple returns the time elapsed from when the animation was started until the passed time.
currentTimeNanos
- value of current time, from System.nanoTime()
, to use in
calculating elapsed time.@NonNull @RegionEffects(value="reads Instance") @Vouch(value="Uses StringBuilder") public java.lang.String toString()
toString
in class java.lang.Object
public void timingSourceTick(TimingSource source, long nanoTime)
timingSourceTick
in interface TimingSource.TickListener
source
- the object that invoked this call.nanoTime
- the current value of the most precise available system timer, in
nanoseconds.