summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorRobert Ly <robertly@google.com>2011-01-19 22:09:47 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-01-19 22:09:47 -0800
commit4c4332250d9e6d2cb746625cc232052561c4d450 (patch)
treea85860edc336dbccc5d4aeb500310de646e67983 /docs
parentada2592b21a55fcb3204fc26ba57d8d56841341b (diff)
parentf99b782b9f3a78fd814d6fd9be9b202142760677 (diff)
downloadframeworks_base-4c4332250d9e6d2cb746625cc232052561c4d450.zip
frameworks_base-4c4332250d9e6d2cb746625cc232052561c4d450.tar.gz
frameworks_base-4c4332250d9e6d2cb746625cc232052561c4d450.tar.bz2
Merge "Doc change: animation devguide topic" into honeycomb
Diffstat (limited to 'docs')
-rw-r--r--docs/html/guide/guide_toc.cs3
-rw-r--r--docs/html/guide/topics/graphics/2d-graphics.jd172
-rw-r--r--docs/html/guide/topics/graphics/animation.jd839
3 files changed, 843 insertions, 171 deletions
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 67f1fec..270d153 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -213,6 +213,9 @@
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
<span class="en">3D with OpenGL</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
+ <span class="en">Animation</span>
+ </a><span class="new">new!</span></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 05f4023..6594568 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -17,8 +17,6 @@ parent.link=index.html
<li><a href="#shape-drawable">Shape Drawable</a></li>
<!-- <li><a href="#state-list">StateListDrawable</a></li> -->
<li><a href="#nine-patch">Nine-patch</a></li>
- <li><a href="#tween-animation">Tween Animation</a></li>
- <li><a href="#frame-animation">Frame Animation</a></li>
</ol>
</div>
</div>
@@ -328,172 +326,4 @@ Notice how the width and height of the button varies with the text, and the back
stretches to accommodate it.
</p>
-<img src="{@docRoot}images/ninepatch_examples.png" alt=""/>
-
-
-<h2 id="tween-animation">Tween Animation</h2>
-
-<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 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.
-Like 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="&#64;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="&#64;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 Java 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>
-
-
-<h2 id="frame-animation">Frame Animation</h2>
-
-<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></code> element as the root node and a series
-of child <code>&lt;item></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">
- &lt;item android:drawable="&#64;drawable/rocket_thrust1" android:duration="200" />
- &lt;item android:drawable="&#64;drawable/rocket_thrust2" android:duration="200" />
- &lt;item android:drawable="&#64;drawable/rocket_thrust3" android:duration="200" />
-&lt;/animation-list>
-</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>
-
+<img src="{@docRoot}images/ninepatch_examples.png" alt=""/> \ No newline at end of file
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
new file mode 100644
index 0000000..c977d51
--- /dev/null
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -0,0 +1,839 @@
+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> \ No newline at end of file