839 lines
39 KiB
Plaintext
Raw Normal View History

page.title=Animation
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li>
<a href="#property-animation">Property Animation</a>
<ol>
<li><a href="#value-animator">Animating with ValueAnimator</a></li>
<li><a href="#object-animator">Animating with ObjectAnimator</a></li>
<li><a href="#type-evaluator">Using the TypeEvaluator</a></li>
<li><a href="#interpolators">Using interpolators</a></li>
<li><a href="#keyframes">Specifying keyframes</a></li>
<li><a href="#choreography">Choreographing multiple animations with AnimatorSet</a></li>
<li><a href="#declaring-xml">Declaring animations in XML</a></li>
</ol>
</li>
<li>
<a href="#view-animation">View Animation</a>
<ol>
<li><a href="#tween-animation">Tween animation</a></li>
<li><a href="#frame-animation">Frame animation</a></li>
</ol>
</li>
</ol>
<h2>Key classes</h2>
<ol>
<li><code><a href=
"/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li>
<li><code><a href=
"/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li>
<li><code><a href=
"/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li>
</ol>
<h2>Related samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API Demos</a></li>
</ol>
</div>
</div>
<p>The Android system provides a flexible animation system that allows you to animate
almost anything, either programmatically or declaratively with XML. There are two
animation systems that you can choose from: <a href="property-animation">property
animation</a> and <a href="#view-animation">view animation</a>. You can use whichever
system that matches your needs, but use only one system for each object that you
are animating.</p>
<h2 id="property-animation">Property Animation</h2>
<p>Introduced in Android 3.0, the property animation system allows you to animate
object properties of any type. <code>int</code>, <code>float</code>,
and hexadecimal color values are supported by default. You can animate any other type by telling the
system how to calculate the values for that given type.</p>
<p>The property animation system allows you to define many aspects of an animation,
such as:</p>
<ul>
<li>Duration</li>
<li>Repeat amount and behavior</li>
<li>Type of time interpolation</li>
<li>Animator sets to play animations together, sequentially, or after specified
delays</li>
<li>Frame refresh delay</li>
</ul>
<p>Most of the property animation system's features can be found in
{@link android.animation android.animation}. Because the
<a href="#view-animation>view animation</a> system already
defines many interpolators in {@link android.view.animation android.view.animation},
you will use those to define your animation's interpolation in the property animation
system as well.
</p>
<p>The following items are the main components of the property animation system:</p>
<dl>
<dt><strong>Animators</strong></dt>
<dd>
The {@link android.animation.Animator} class provides the basic structure for
creating animations. You normally do not use this class directly as it only provides
minimal functionality that must be extended to fully support animating values.
The following subclasses extend {@link android.animation.Animator}, which you might find more useful:
<ul>
<li>{@link android.animation.ValueAnimator} is the main timing engine for
property animation and computes the values for the property to be animated.
{@link android.animation.ValueAnimator} only computes the animation values and is
not aware of the specific object and property that is being animated or what the
values might be used for. You must listen for updates to values calculated by the
{@link android.animation.ValueAnimator} and process the data with your own logic.
See the section about <a href="#value-animator">Animating with ValueAnimator</a>
for more information.</li>
<li>{@link android.animation.ObjectAnimator} is a subclass of {@link
android.animation.ValueAnimator} and allows you to set a target object and object
property to animate. This class is aware of the object and property to be
animated, and updates the property accordingly when it computes a new value for
the animation. See the section about <a href="#object-animator">
Animating with ObjectAnimator</a> for more information.</li>
<li>{@link android.animation.AnimatorSet} provides a mechanism to group
animations together so that they are rendered in relation to one another. You can
set animations to play together, sequentially, or after a specified delay.
See the section about <a href="#choreography">
Choreographing multiple animations with Animator Sets</a> for more information.</li>
</ul>
</dd>
<dt><strong>Evaluators</strong></dt>
<dd>
<p>If you are animating an object property that is <em>not</em> an <code>int</code>,
<code>float</code>, or color, implement the {@link android.animation.TypeEvaluator}
interface to specify how to compute the object property's animated values. You give
a {@link android.animation.TypeEvaluator} the timing data that is provided by an
{@link android.animation.Animator} class, the animation's start and end value, and
provide logic that computes the animated values of the property based on this data.</p>
<p>You can also specify a custom {@link android.animation.TypeEvaluator} for
<code>int</code>, <code>float</code>, and color values as well, if you want to
process those types differently than the default behavior.</p>
<p>See <a href="#type-evaluator">Using a TypeEvaluator</a> for more information on
how to write a custom evaluator.</p>
</dd>
<dt><strong>Interpolators</strong></dt>
<dd>
<p>A time interpolator defines how specific values in an animation are calculated
as a function of time. For example, you can specify animations to happen linearly
across the whole animation, meaning the animation moves evenly the entire time, or
you can specify animations to use non-linear time, for example, using acceleration
or deceleration at the beginning or end of the animation.</p>
<p>The Android system provides a set of common interpolators in
{@link android.view.animation android.view.animation}. If none of these suits your needs, you
can implement the {@link android.animation.TimeInterpolator} interface and create
your own. See <a href="#interpolators">Interpolators</a> for more information on
how to write a custom interpolator.</p>
</dd>
</dl>
<p>The <code>com.example.android.apis.animation</code> package in the <a href=
"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
API Demos</a> sample project also provides a good overview and many examples on how to
use the property animation system.</p>
<h3>How the property animation system calculates animated values</h3>
<p>When you call {@link android.animation.ValueAnimator#start start()} to begin an animation,
the {@link android.animation.ValueAnimator} calculates
an <em>elapsed fraction</em> between 0 and 1, based on the duration of the animation
and how much time has elapsed. The elapsed fraction represents the percentage of time
that the animation has completed, 0 meaning 0% and 1 meaning 100%. The Animator then
calls the {@link android.animation.TimeInterpolator} that is currently set,
to calculate an <em>eased fraction</em>,
which is a modified value of the elapsed fraction that takes into account the interpolator that
is set (time interpolation is often referred to as <em>easing</em>). The eased fraction
is the final value that is used to animate the property.</p>
<p>Once the eased fraction is calculated, {@link android.animation.ValueAnimator} calls
the appropriate {@link android.animation.TypeEvaluator} to calculate the final value of
the property that you are animating, based on the eased fraction, the starting value,
and ending value of the animation.</p>
<h3 id="value-animator">Animating with ValueAnimator</h3>
<p>The {@link android.animation.ValueAnimator} class lets you animate values of some
type for the duration of an animation by specifying a set of <code>int</code>,
<code>float</code>, or color values to animate over and the duration of the animation.
You obtain a {@link android.animation.ValueAnimator} by calling one of its factory
methods: {@link android.animation.ValueAnimator#ofInt ofInt()},
{@link android.animation.ValueAnimator#ofFloat ofFloat()},
or {@link android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
<pre>ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();
</pre>
<p>In this code, the {@link android.animation.ValueAnimator} starts
calculating the values of the animation, between 0 and 1, for
a duration of 1000 ms, when the <code>start()</code> method runs.</p>
<p>You can also specify a custom type to animate by doing the following:</p>
<pre>ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();
</pre>
<p>In this code, the {@link android.animation.ValueAnimator} starts
calculating the values of the animation, between <code>startPropertyValue</code> and
<code>endPropertyValue</code> using the logic supplied by <code>MyTypeEvaluator</code>
for a duration of 1000 ms, when the {@link android.animation.ValueAnimator#start start()}
method runs.</p>
<p>The previous code snippets, however, do not affect an object, because the {@link
android.animation.ValueAnimator} does not operate on objects or properties directly. To
use the results of a {@link android.animation.ValueAnimator}, you must define listeners
in the {@link android.animation.ValueAnimator} to appropriately handle important events
during the animation's lifespan, such as frame updates. You can implement the following
interfaces to create listeners for {@link android.animation.ValueAnimator}:</p>
<ul>
<li>{@link android.animation.Animator.AnimatorListener}
<ul>
<li>{@link android.animation.Animator.AnimatorListener#onAnimationStart
onAnimationStart()} - Called when the animation starts</li>
<li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd
onAnimationEnd()} - Called when the animation ends.</li>
<li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
onAnimationRepeat()} - Called when the animation repeats itself.</li>
<li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
onAnimationCancel()} - Called when the animation is canceled.</li>
</ul>
</li>
<li>{@link android.animation.ValueAnimator.AnimatorUpdateListener}
<ul>
<li>
<p>{@link
android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
onAnimationUpdate()} - called on every frame of the animation.
Listen to this event to use the calculated values generated by
{@link android.animation.ValueAnimator} during an animation. To use the value,
query the {@link android.animation.ValueAnimator} object passed into the event
to get the current animated value with the
{@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method.</p>
<p>If you are animating your own custom object (not View objects), this
callback must also call the {@link android.view.View#invalidate invalidate()}
method to force a redraw of the screen. If you are animating View objects,
{@link android.view.View#invalidate invalidate()} is automatically called when
a property of the View is changed.</p>
</li>
</ul>
<p>You can extend the {@link android.animation.AnimatorListenerAdapter} class
instead of implementing the {@link android.animation.Animator.AnimatorListener}
interface, if you do not want to implement all of the methods of the {@link
android.animation.Animator.AnimatorListener} interface. The {@link
android.animation.AnimatorListenerAdapter} class provides empty implementations of the
methods that you can choose to override.</p>
</li>
</ul>
<p>For example, the <a href=
"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
Bouncing Balls</a> sample in the API demos creates an {@link
android.animation.AnimatorListenerAdapter} for just the {@link
android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
callback:</p>
<pre>ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
balls.remove(((ObjectAnimator)animation).getTarget());
}
</pre>
<h3 id="object-animator">Animating with ObjectAnimator</h3>
<p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
android.animation.ValueAnimator} (discussed in the previous section)
and combines the timing engine and value computation
of {@link android.animation.ValueAnimator} with the ability to animate a named property
of a target object. This makes animating any object much easier, as you no longer need
to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener}, because
the animated property updates automatically.</p>
<p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
android.animation.ValueAnimator}, but you also specify the object and that object's
property (as a String) that you want to animate:</p>
<pre>
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();
</pre>
<p>To have the {@link android.animation.ObjectAnimator} update properties correctly,
you must do the following:</p>
<ul>
<li>The object property that you are animating must have a setter function in the
form of <code>set&lt;propertyName&gt;()</code>. Because the {@link
android.animation.ObjectAnimator} automatically updates the property during
animation, it must be able to access the property with this setter method. For
example, if the property name is <code>foo</code>, you need to have a
<code>setFoo()</code> method. If this setter method does not exist, you have three
options:
<ul>
<li>Add the setter method to the class if you have the rights to do so.</li>
<li>Use a wrapper class that you have rights to change and have that wrapper
receive the value with a valid setter method and forward it to the original
object.</li>
<li>Use {@link android.animation.ValueAnimator} instead.</li>
</ul>
</li>
<li>If you specify only one value for the <code>values...</code> parameter,
in one of the {@link android.animation.ObjectAnimator} factory methods, it is assumed to be
the ending value of the animation. Therefore, the object property that you are
animating must have a getter function that is used to obtain the starting value of
the animation. The getter function must be in the form of
<code>get&lt;propertyName&gt;()</code>. For example, if the property name is
<code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
<li>The getter (if needed) and setter methods of the property that you are animating must
return the same type as the starting and ending values that you specify to {@link
android.animation.ObjectAnimator}. For example, you must have
<code>targetObject.setPropName(float)</code> and
<code>targetObject.getPropName(float)</code> if you construct the following {@link
android.animation.ObjectAnimator}:
<pre>ObjectAnimator.ofFloat(targetObject, "propName", 1f)</pre>
</li>
</ul>
<h3 id="type-evaluator">Using the TypeEvaluator</h3>
<p>If you want to animate a type that is unknown to the Android system,
you can create your own evaluator by implementing the {@link
android.animation.TypeEvaluator} interface. The types that are known by the Android
system are <code>int</code>, <code>float</code>, or a color, which are supported by the
{@link android.animation.IntEvaluator}, {@link android.animation.FloatEvaluator}, and
{@link android.animation.ArgbEvaluator} type evaluators.</p>
<p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method.
This allows the animator that you are using to return an
appropriate value for your animated property at the current point of the animation. The
{@link android.animation.FloatEvaluator} class demonstrates how to do this:</p>
<pre>
public class FloatEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
}
}
</pre>
<p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or
{@link android.animation.ObjectAnimator}) runs, it calculates a current elapsed
fraction of the animation (a value between 0 and 1) and then calculates an eased
version of that depending on what interpolator that you are using. The eased fraction
is what your {@link android.animation.TypeEvaluator} receives through the <code>fraction</code>
parameter, so you do not have to take into account the interpolator
when calculating animated values.</p>
<h3 id="interpolators">Using Interpolators</h3>
<p>An interpolator define how specific values in an animation are
calculated as a function of time. For example, you can specify animations to happen
linearly across the whole animation, meaning the animation moves evenly the entire
time, or you can specify animations to use non-linear time, for example, using
acceleration or deceleration at the beginning or end of the animation.</p>
<p>Interpolators in the animation system receive a fraction from Animators that represent the elapsed time
of the animation. Interpolators modify this fraction to coincide with the type of
animation that it aims to provide. The Android system provides a set of common
interpolators in the {@link android.view.animation android.view.animation package}. If
none of these suit your needs, you can implement the {@link
android.animation.TimeInterpolator} interface and create your own.</p>
<p>As an example, how the default interpolator {@link
android.view.animation.AccelerateDecelerateInterpolator} and the {@link
android.view.animation.LinearInterpolator} calculate eased fractions are compared below. The {@link
android.view.animation.LinearInterpolator} has no effect on the elapsed fraction,
because a linear interpolation is calculated the same way as the elapsed fraction. The
{@link android.view.animation.AccelerateDecelerateInterpolator} accelerates into the
animation and decelerates out of it. The following methods define the logic for these
interpolators:</p>
<p><strong>AccelerateDecelerateInterpolator</strong></p>
<pre>public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}</pre>
<p><strong>LinearInterpolator</strong></p>
<pre>public float getInterpolation(float input) {
return input;
}</pre>
<p>The following table represents the approximate values that are calculated by these
interpolators for an animation that lasts 1000ms:</p>
<table>
<tr>
<th>ms elapsed</th>
<th>Elapsed fraction/Eased fraction (Linear)</th>
<th>Eased fraction (Accelerate/Decelerate)</th>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>200</td>
<td>.2</td>
<td>.1</td>
</tr>
<tr>
<td>400</td>
<td>.4</td>
<td>.345</td>
</tr>
<tr>
<td>600</td>
<td>.6</td>
<td>.8</td>
</tr>
<tr>
<td>800</td>
<td>.8</td>
<td>.9</td>
</tr>
<tr>
<td>1000</td>
<td>1</td>
<td>1</td>
</tr>
</table>
<p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes
the values at the same speed, .2 for every 200ms that passes. The {@link
android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than
{@link android.view.animation.LinearInterpolator} between 200ms and 600ms and slower
between 600ms and 1000ms.</p>
<h3 id="keyframes">Specifying Keyframes</h3>
<p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets
you define a specific state at a specific time of an animation. Each keyframe can also
have its own interpolator to control the behavior of the animation in the interval
between the previous keyframe's time and the time of this keyframe.</p>
<p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the
factory methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
android.animation.Keyframe#ofFloat ofFloat()}, or {@link
android.animation.Keyframe#ofObject ofObject()} to obtain the appropriate type of
{@link android.animation.Keyframe}. You then call the {@link
android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the
object, you can obtain an animator by passing in the {@link
android.animation.PropertyValuesHolder} object and the object to animate. The following
code snippet demonstrates how to do this:</p>
<pre>
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
rotationAnim.setDuration(5000ms);
</pre>For a more complete example on how to use keyframes, see the <a href=
"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
MultiPropertyAnimation</a> sample in APIDemos.
<h3 id="choreography">Choreographing multiple animations with Animator Sets</h3>
<p>In many cases, you want to play an animation that depends on when another animation
starts or finishes. The Android system lets you bundle animations together into an
{@link android.animation.AnimatorSet}, so that you can specify whether to start animations
simultaneously, sequentially, or after a specified delay. You can also nest {@link
android.animation.AnimatorSet} objects within each other.</p>
<p>The following sample code taken from the <a href=
"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
Bouncing Balls</a> sample (modified for simplicity) plays the following
{@link android.animation.Animator} objects in the following manner:</p>
<ol>
<li>Plays <code>bounceAnim</code>.</li>
<li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>,
<code>stretchAnim1</code>, and <code>stretchAnim2</code> at the same time.</li>
<li>Plays <code>bounceBackAnim</code>.</li>
<li>Plays <code>fadeAnim</code>.</li>
</ol>
<pre>AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();
</pre>
<p>For a more complete example on how to use animator sets, see the <a href=
"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
Bouncing Balls</a> sample in APIDemos.</p>
<h3 id="declaring-xml">Declaring animations in XML</h3>
<p>As with <a href="view-animation">view animation</a>, you can declare property animations with
XML instead of doing it programmatically. The following Android classes also have XML
declaration support with the following XML tags:</p>
<ul>
<li>{@link android.animation.ValueAnimator} - <code>&lt;animator&gt;</code></li>
<li>{@link android.animation.ObjectAnimator} - <code>&lt;objectAnimator&gt;</code></li>
<li>{@link android.animation.AnimatorSet} - <code>&lt;AnimatorSet&gt;</code></li>
</ul>
<p>Both <code>&lt;animator&gt;</code> ({@link android.animation.ValueAnimator}) and
<code>&lt;objectAnimator&gt;</code> ({@link android.animation.ObjectAnimator}) have the
following attributes:</p>
<dl>
<dt><code>android:duration</code></dt>
<dd>The number of milliseconds that the animation runs.</dd>
<dt><code>android:valueFrom</code> and <code>android:valueTo</code></dt>
<dd>The values being animated
between. These are restricted to numbers (<code>float</code> or <code>int</code>) in
XML. They can be <code>float</code>, <code>int</code>, or any kind of
<code>Object</code> when creating animations programmatically.</dd>
<dt><code>android:valueType</code></dt>
<dd>Set to either <code>"floatType"</code> or <code>"intType"</code>.</dd>
<dt><code>android:startDelay</code></dt>
<dd>The delay, in milliseconds, before the animation begins
playing (after calling {@link android.animation.ValueAnimator#start start()}).</dd>
<dt><code>android:repeatCount</code></dt>
<dd>How many times to repeat an animation. Set to
<code>"-1"</code> for infinite repeating or to a positive integer. For example, a value of
<code>"1"</code> means that the animation is repeated once after the initial run of the
animation, so the animation plays a total of two times. The default value is
<code>"0"</code>.</dd>
<dt><code>android:repeatMode</code></dt>
<dd>How an animation behaves when it reaches the end of the
animation. <code>android:repeatCount</code> must be set to a positive integer or
<code>"-1"</code> for this attribute to have an effect. Set to <code>"reverse"</code> to
have the animation reverse direction with each iteration or <code>"repeat"</code> to
have the animation loop from the beginning each time.</dd>
</dl>
<p>The <code>objectAnimator</code> ({@link android.animation.ObjectAnimator}) element has the
additional attribute <code>propertyName</code>, that lets you specify the name of the
property being animated. The <code>objectAnimator</code> element does not expose a
<code>target</code> attribute, however, so you cannot set the object to animate in the
XML declaration. You have to inflate the XML resource by calling
{@link android.animation.AnimatorInflater#loadAnimator loadAnimator()} and call
{@link android.animation.ObjectAnimator#setTarget setTarget()} to set the target object, before calling
{@link android.animation.ObjectAnimator#start start()}.</p>
<p>The <code>set</code> element ({@link android.animation.AnimatorSet}) exposes a single
attribute, <code>ordering</code>. Set this attribute to <code>together</code> (default)
to play all the animations in this set at once. Set this attribute to
<code>sequentially</code> to play the animations in the order they are declared.</p>
<p>You can specify nested <code>set</code> tags to further group animations together.
The animations that you want to group together should be children of the
<code>set</code> tag and can define their own <code>ordering</code> attribute.</p>
<p>As an example, this XML code creates an {@link android.animation.AnimatorSet} object
that animates x and y at the same time (<code>together</code> is the default ordering
when nothing is specified), then runs an animation that fades an object out:</p>
<pre>&lt;set android:ordering="sequentially"&gt;
&lt;set&gt;
&lt;objectAnimator
android:propertyName="x"
android:duration="500"
android:valueTo="400"
android:valueType="int"/&gt;
&lt;objectAnimator
android:propertyName="y"
android:duration="500"
android:valueTo="300"
android:valueType="int" &gt;
&lt;/set&gt;
&lt;objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="0f"/&gt;
&lt;/set&gt;
</pre>
<p>In order to run this animation, you must inflate the XML resources in your code to
an {@link android.animation.AnimatorSet} object, and then set the target objects for all of
the animations before starting the animation set. Calling {@link
android.animation.AnimatorSet#setTarget setTarget()} sets a single target object for
all children of the {@link android.animation.AnimatorSet}.</p>
<h2 id="view-animation">View Animation</h2>You can use View Animation in any View
object to perform tweened animation and frame by frame animation. Tween animation
calculates the animation given information such as the start point, end point, size,
rotation, and other common aspects of an animation. Frame by frame animation lets you
load a series of Drawable resources one after another to create an animation.
<h3 id="tween-animation">Tween Animation</h3>
<p>A tween animation can perform a series of simple transformations (position, size,
rotation, and transparency) on the contents of a View object. So, if you have a
{@link android.widget.TextView} object, you can move, rotate, grow, or shrink the text. If it has a background
image, the background image will be transformed along with the text. The {@link
android.view.animation animation package} provides all the classes used in a tween
animation.</p>
<p>A sequence of animation instructions defines the tween animation, defined by either
XML or Android code. As with defining a layout, an XML file is recommended because it's
more readable, reusable, and swappable than hard-coding the animation. In the example
below, we use XML. (To learn more about defining an animation in your application code,
instead of XML, refer to the {@link android.view.animation.AnimationSet} class and
other {@link android.view.animation.Animation} subclasses.)</p>
<p>The animation instructions define the transformations that you want to occur, when
they will occur, and how long they should take to apply. Transformations can be
sequential or simultaneous &mdash; for example, you can have the contents of a TextView
move from left to right, and then rotate 180 degrees, or you can have the text move and
rotate simultaneously. Each transformation takes a set of parameters specific for that
transformation (starting size and ending size for size change, starting angle and
ending angle for rotation, and so on), and also a set of common parameters (for
instance, start time and duration). To make several transformations happen
simultaneously, give them the same start time; to make them sequential, calculate the
start time plus the duration of the preceding transformation.</p>
<p>The animation XML file belongs in the <code>res/anim/</code> directory of your
Android project. The file must have a single root element: this will be either a single
<code>&lt;alpha&gt;</code>, <code>&lt;scale&gt;</code>, <code>&lt;translate&gt;</code>,
<code>&lt;rotate&gt;</code>, interpolator element, or <code>&lt;set&gt;</code> element
that holds groups of these elements (which may include another
<code>&lt;set&gt;</code>). By default, all animation instructions are applied
simultaneously. To make them occur sequentially, you must specify the
<code>startOffset</code> attribute, as shown in the example below.</p>
<p>The following XML from one of the ApiDemos is used to stretch, then simultaneously
spin and rotate a View object.</p>
<pre>
&lt;set android:shareInterpolator="false"&gt;
&lt;scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" /&gt;
&lt;set android:interpolator="@android:anim/decelerate_interpolator"&gt;
&lt;scale
android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400"
android:fillBefore="false" /&gt;
&lt;rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400" /&gt;
&lt;/set&gt;
&lt;/set&gt;
</pre>
<p>Screen coordinates (not used in this example) are (0,0) at the upper left hand
corner, and increase as you go down and to the right.</p>
<p>Some values, such as pivotX, can be specified relative to the object itself or
relative to the parent. Be sure to use the proper format for what you want ("50" for
50% relative to the parent, or "50%" for 50% relative to itself).</p>
<p>You can determine how a transformation is applied over time by assigning an {@link
android.view.animation.Interpolator}. Android includes several Interpolator subclasses
that specify various speed curves: for instance, {@link
android.view.animation.AccelerateInterpolator} tells a transformation to start slow and
speed up. Each one has an attribute value that can be applied in the XML.</p>
<p>With this XML saved as <code>hyperspace_jump.xml</code> in the
<code>res/anim/</code> directory of the project, the following code will reference
it and apply it to an {@link android.widget.ImageView} object from the layout.</p>
<pre>
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
</pre>
<p>As an alternative to <code>startAnimation()</code>, you can define a starting time
for the animation with <code>{@link android.view.animation.Animation#setStartTime(long)
Animation.setStartTime()}</code>, then assign the animation to the View with
<code>{@link android.view.View#setAnimation(android.view.animation.Animation)
View.setAnimation()}</code>.</p>
<p>For more information on the XML syntax, available tags and attributes, see <a href=
"{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
<p class="note"><strong>Note:</strong> Regardless of how your animation may move or
resize, the bounds of the View that holds your animation will not automatically adjust
to accommodate it. Even so, the animation will still be drawn beyond the bounds of its
View and will not be clipped. However, clipping <em>will occur</em> if the animation
exceeds the bounds of the parent View.</p>
<h3 id="frame-animation">Frame Animation</h3>
<p>This is a traditional animation in the sense that it is created with a sequence of
different images, played in order, like a roll of film. The {@link
android.graphics.drawable.AnimationDrawable} class is the basis for frame
animations.</p>
<p>While you can define the frames of an animation in your code, using the {@link
android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished
with a single XML file that lists the frames that compose the animation. Like the tween
animation above, the XML file for this kind of animation belongs in the
<code>res/drawable/</code> directory of your Android project. In this case, the
instructions are the order and duration for each frame of the animation.</p>
<p>The XML file consists of an <code>&lt;animation-list&gt;</code> element as the root
node and a series of child <code>&lt;item&gt;</code> nodes that each define a frame: a
drawable resource for the frame and the frame duration. Here's an example XML file for
a frame-by-frame animation:</p>
<pre>
&lt;animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true"&gt;
&lt;item android:drawable="@drawable/rocket_thrust1" android:duration="200" /&gt;
&lt;item android:drawable="@drawable/rocket_thrust2" android:duration="200" /&gt;
&lt;item android:drawable="@drawable/rocket_thrust3" android:duration="200" /&gt;
&lt;/animation-list&gt;
</pre>
<p>This animation runs for just three frames. By setting the
<code>android:oneshot</code> attribute of the list to <var>true</var>, it will cycle
just once then stop and hold on the last frame. If it is set <var>false</var> then the
animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the
<code>res/drawable/</code> directory of the project, it can be added as the background
image to a View and then called to play. Here's an example Activity, in which the
animation is added to an {@link android.widget.ImageView} and then animated when the
screen is touched:</p>
<pre>
AnimationDrawable rocketAnimation;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
rocketAnimation.start();
return true;
}
return super.onTouchEvent(event);
}
</pre>
<p>It's important to note that the <code>start()</code> method called on the
AnimationDrawable cannot be called during the <code>onCreate()</code> method of your
Activity, because the AnimationDrawable is not yet fully attached to the window. If you
want to play the animation immediately, without requiring interaction, then you might
want to call it from the <code>{@link
android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code>
method in your Activity, which will get called when Android brings your window into
focus.</p>
<p>For more information on the XML syntax, available tags and attributes, see <a href=
"{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>