diff options
-rw-r--r-- | core/java/android/animation/package.html | 19 | ||||
-rw-r--r-- | docs/html/guide/guide_toc.cs | 3 | ||||
-rw-r--r-- | docs/html/guide/topics/graphics/2d-graphics.jd | 172 | ||||
-rw-r--r-- | docs/html/guide/topics/graphics/animation.jd | 839 |
4 files changed, 860 insertions, 173 deletions
diff --git a/core/java/android/animation/package.html b/core/java/android/animation/package.html index b66669b..ff43260 100644 --- a/core/java/android/animation/package.html +++ b/core/java/android/animation/package.html @@ -1,6 +1,21 @@ <html> <body> -Provides classes for animating values over time, and setting those values on target -objects. +<p> +These classes provide functionality for the property animation system, which 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 with a custom {@link android.animation.TypeEvaluator}. +</p> + +<p> +You can set many different types of interpolators (contained in {@link android.view.animation}), +specify {@link android.animation.Keyframe keyframes}, or group animations to play sequentially +or simultaneously (with {@link android.animation.AnimatorSet}) to further control your animation +behaviors.</p> + +<p> +For a guide on how to use the property animation system, see the +<a href="{@docRoot}guide/topics/media/index.html">Animation</a> developer guide. +</p> </body> </html> 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 — -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><alpha></code>, -<code><scale></code>, <code><translate></code>, <code><rotate></code>, interpolator element, -or <code><set></code> element that holds groups of these elements (which may include another -<code><set></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> -<set android:shareInterpolator="false"> - <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" /> - <set android:interpolator="@android:anim/decelerate_interpolator"> - <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" /> - <rotate - android:fromDegrees="0" - android:toDegrees="-45" - android:toYScale="0.0" - android:pivotX="50%" - android:pivotY="50%" - android:startOffset="700" - android:duration="400" /> - </set> -</set> -</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><animation-list></code> element as the root node and a series -of child <code><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> -<animation-list xmlns:android="http://schemas.android.com/apk/res/android" - android:oneshot="true"> - <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> - <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> - <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> -</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<propertyName>()</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<propertyName>()</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><animator></code></li> + + <li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li> + + <li>{@link android.animation.AnimatorSet} - <code><AnimatorSet></code></li> + </ul> + + <p>Both <code><animator></code> ({@link android.animation.ValueAnimator}) and + <code><objectAnimator></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><set android:ordering="sequentially"> + <set> + <objectAnimator + android:propertyName="x" + android:duration="500" + android:valueTo="400" + android:valueType="int"/> + <objectAnimator + android:propertyName="y" + android:duration="500" + android:valueTo="300" + android:valueType="int" > + </set> + <objectAnimator + android:propertyName="alpha" + android:duration="500" + android:valueTo="0f"/> + </set> +</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 — 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><alpha></code>, <code><scale></code>, <code><translate></code>, + <code><rotate></code>, interpolator element, or <code><set></code> element + that holds groups of these elements (which may include another + <code><set></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> +<set android:shareInterpolator="false"> + <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" /> + <set android:interpolator="@android:anim/decelerate_interpolator"> + <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" /> + <rotate + android:fromDegrees="0" + android:toDegrees="-45" + android:toYScale="0.0" + android:pivotX="50%" + android:pivotY="50%" + android:startOffset="700" + android:duration="400" /> + </set> +</set> +</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><animation-list></code> element as the root + node and a series of child <code><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> +<animation-list xmlns:android="http://schemas.android.com/apk/res/android" + android:oneshot="true"> + <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> + <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> + <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> +</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>
\ No newline at end of file |