page.title=Property Animation parent.title=Graphics parent.link=index.html @jd:body

In this document

  1. What is Property Animation?
    1. How property animation works
  2. Animating with ValueAnimator
  3. Animating with ObjectAnimator
  4. Choreographing Multiple Animations with AnimatorSet
  5. Animation Listeners
  6. Using a TypeEvaluator
  7. Using Interpolators
  8. Specifying Keyframes
  9. Animating Layout Changes to ViewGroups
  10. Animating Views
  11. Declaring Animations in XML

Key classes

  1. ValueAnimator
  2. ObjectAnimator
  3. TypeEvaluator

Related samples

  1. API Demos

Introduced in Android 3.0, the property animation system is a robust framework that allows you to animate almost anything. Property animation is not confined to objects drawn on the screen. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not.The property animation system also has a few advantages over the view animation system, which makes it more flexible to use.

The view animation system provides the capability to only animate View objects, so if you wanted to animate non-View objects, you had to implement your own code to do so. The view animation system also was constrained in the fact that it only exposed a few aspects of a View object to animate, such as the scaling and rotation of a View but not the background color for instance.

Another disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this. With the property animation system, these constraints are completely removed, and you can animate any property of any object, including View objects, and the object itself is actually modified.

The view animation system, however, takes less time to setup and requires less code to write. If view animation accomplishes everything that you need to do, or if your existing code already works the way you want, there is no need to use the property animation system.

What is Property Animation?

A property animation changes a property's (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object's position on the screen, how long you want to animate it for, and what values you want to animate between.

The property animation system lets you define the following characteristics of an animation:

How the property animation system works

First, let's go over how an animation works with a simple example. Figure 1 depicts a hypothetical object that is animated with its x property, which represents its horizontal location on a screen. The duration of the animation is set to 40 ms and the distance to travel is 40 pixels. Every 10 ms, which is the default frame refresh rate, the object moves horizontally by 10 pixels. At the end of 40ms, the animation stops, and the object ends at horizontal position 40. This is an example of an animation with linear interpolation, meaning the object moves at a constant speed.

Figure 1. Example of a linear animation

You can also specify animations to have a non-linear interpolation. Figure 2 illustrates a hypothetical object that accelerates at the beginning of the animation, and decelerates at the end of the animation. The object still moves 40 pixels in 40 ms, but non-linearly. In the beginning, this animation accelerates up to the halfway point then decelerates from the halfway point until the end of the animation. As Figure 2 shows, the distance traveled at the beginning and end of the animation is less than in the middle.

Figure 2. Example of a non-linear animation

Let's take a detailed look at how the important components of the property animation system would calculate animations like the ones illustrated above. Figure 3 depicts how the main classes work with one another.

Figure 3. How animations are calculated

The {@link android.animation.ValueAnimator} object keeps track of your animation's timing, such as how long the animation has been running, and the current value of the property that it is animating.

The {@link android.animation.ValueAnimator} encapsulates a {@link android.animation.TimeInterpolator}, which defines animation interpolation, and a {@link android.animation.TypeEvaluator}, which defines how to calculate values for the property being animated. For example, in Figure 2, the {@link android.animation.TimeInterpolator} used would be {@link android.view.animation.AccelerateDecelerateInterpolator} and the {@link android.animation.TypeEvaluator} would be {@link android.animation.IntEvaluator}.

To start an animation, create a {@link android.animation.ValueAnimator} and give it the starting and ending values for the property that you want to animate, along with the duration of the animation. When you call {@link android.animation.ValueAnimator#start start()} the animation begins. During the whole animation, the {@link android.animation.ValueAnimator} calculates an elapsed fraction 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%. For example, in Figure 1, the elapsed fraction at t = 10 ms would be .25 because the total duration is t = 40 ms.

When the {@link android.animation.ValueAnimator} is done calculating an elapsed fraction, it calls the {@link android.animation.TimeInterpolator} that is currently set, to calculate an interpolated fraction. An interpolated fraction maps the elapsed fraction to a new fraction that takes into account the time interpolation that is set. For example, in Figure 2, because the animation slowly accelerates, the interpolated fraction, about .15, is less than the elapsed fraction, .25, at t = 10 ms. In Figure 1, the interpolated fraction is always the same as the elapsed fraction.

When the interpolated fraction is calculated, {@link android.animation.ValueAnimator} calls the appropriate {@link android.animation.TypeEvaluator}, to calculate the value of the property that you are animating, based on the interpolated fraction, the starting value, and the ending value of the animation. For example, in Figure 2, the interpolated fraction was .15 at t = 10 ms, so the value for the property at that time would be .15 X (40 - 0), or 6.

The com.example.android.apis.animation package in the API Demos sample project provides many examples on how to use the property animation system.

API Overview

You can find most of the property animation system's APIs in {@link android.animation android.animation}. Because the view animation system already defines many interpolators in {@link android.view.animation android.view.animation}, you can use those interpolators in the property animation system as well. The following tables describe the main components of the property animation system.

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}:

Table 1. Animators

Class Description
{@link android.animation.ValueAnimator} The main timing engine for property animation that also computes the values for the property to be animated. It has all of the core functionality that calculates animation values and contains the timing details of each animation, information about whether an animation repeats, listeners that receive update events, and the ability to set custom types to evaluate. There are two pieces to animating properties: calculating the animated values and setting those values on the object and property that is being animated. {@link android.animation.ValueAnimator} does not carry out the second piece, so you must listen for updates to values calculated by the {@link android.animation.ValueAnimator} and modify the objects that you want to animate with your own logic. See the section about Animating with ValueAnimator for more information.
{@link android.animation.ObjectAnimator} A subclass of {@link android.animation.ValueAnimator} that allows you to set a target object and object property to animate. This class updates the property accordingly when it computes a new value for the animation. You want to use {@link android.animation.ObjectAnimator} most of the time, because it makes the process of animating values on target objects much easier. However, you sometimes want to use {@link android.animation.ValueAnimator} directly because {@link android.animation.ObjectAnimator} has a few more restrictions, such as requiring specific acessor methods to be present on the target object.
{@link android.animation.AnimatorSet} Provides a mechanism to group animations together so that they run in relation to one another. You can set animations to play together, sequentially, or after a specified delay. See the section about Choreographing multiple animations with Animator Sets for more information.

Evaluators tell the property animation system how to calculate values for a given property. They take the timing data that is provided by an {@link android.animation.Animator} class, the animation's start and end value, and calculate the animated values of the property based on this data. The property animation system provides the following evaluators:

Table 2. Evaluators

Class/Interface Description
{@link android.animation.IntEvaluator} The default evaluator to calculate values for int properties.
{@link android.animation.FloatEvaluator} The default evaluator to calculate values for float properties.
{@link android.animation.ArgbEvaluator} The default evaluator to calculate values for color properties that are represented as hexidecimal values.
{@link android.animation.TypeEvaluator} An interface that allows you to create your own evaluator. If you are animating an object property that is not an int, float, or color, you must implement the {@link android.animation.TypeEvaluator} interface to specify how to compute the object property's animated values. You can also specify a custom {@link android.animation.TypeEvaluator} for int, float, and color values as well, if you want to process those types differently than the default behavior. See the section about Using a TypeEvaluator for more information on how to write a custom evaluator.

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, accelerating at the beginning and decelerating at the end of the animation. Table 3 describes the interpolators that are contained in {@link android.view.animation android.view.animation}. If none of the provided interpolators suits your needs, implement the {@link android.animation.TimeInterpolator} interface and create your own. See Using interpolators for more information on how to write a custom interpolator.

Table 3. Interpolators

Class/Interface Description
{@link android.view.animation.AccelerateDecelerateInterpolator} An interpolator whose rate of change starts and ends slowly but accelerates through the middle.
{@link android.view.animation.AccelerateInterpolator} An interpolator whose rate of change starts out slowly and then accelerates.
{@link android.view.animation.AnticipateInterpolator} An interpolator whose change starts backward then flings forward.
{@link android.view.animation.AnticipateOvershootInterpolator} An interpolator whose change starts backward, flings forward and overshoots the target value, then finally goes back to the final value.
{@link android.view.animation.BounceInterpolator} An interpolator whose change bounces at the end.
{@link android.view.animation.CycleInterpolator} An interpolator whose animation repeats for a specified number of cycles.
{@link android.view.animation.DecelerateInterpolator} An interpolator whose rate of change starts out quickly and and then decelerates.
{@link android.view.animation.LinearInterpolator} An interpolator whose rate of change is constant.
{@link android.view.animation.OvershootInterpolator} An interpolator whose change flings forward and overshoots the last value then comes back.
{@link android.animation.TimeInterpolator} An interface that allows you to implement your own interpolator.

Animating with ValueAnimator

The {@link android.animation.ValueAnimator} class lets you animate values of some type for the duration of an animation by specifying a set of int, float, or color values to animate through. 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:

ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();        

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 start() method runs.

You can also specify a custom type to animate by doing the following:

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();        

In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the animation, between startPropertyValue and endPropertyValue using the logic supplied by MyTypeEvaluator for a duration of 1000 ms, when the {@link android.animation.ValueAnimator#start start()} method runs.

The previous code snippets, however, has no real effect on an object, because the {@link android.animation.ValueAnimator} does not operate on objects or properties directly. The most likely thing that you want to do is modify the objects that you want to animate with these calculated values. You do this by defining listeners in the {@link android.animation.ValueAnimator} to appropriately handle important events during the animation's lifespan, such as frame updates. When implementing the listeners, you can obtain the calculated value for that specific frame refresh by calling {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()}. For more information on listeners, see the section about Animation Listeners.

Animating with ObjectAnimator

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.

Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link android.animation.ValueAnimator}, but you also specify the object and the name of that object's property (as a String) along with the values to animate between:

ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();

To have the {@link android.animation.ObjectAnimator} update properties correctly, you must do the following:

Choreographing Multiple Animations with AnimatorSet

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.

The following sample code taken from the Bouncing Balls sample (modified for simplicity) plays the following {@link android.animation.Animator} objects in the following manner:

  1. Plays bounceAnim.
  2. Plays squashAnim1, squashAnim2, stretchAnim1, and stretchAnim2 at the same time.
  3. Plays bounceBackAnim.
  4. Plays fadeAnim.
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();

For a more complete example on how to use animator sets, see the Bouncing Balls sample in APIDemos.

Animation Listeners

You can listen for important events during an animation's duration with the listeners described below.

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.

For example, the Bouncing Balls sample in the API demos creates an {@link android.animation.AnimatorListenerAdapter} for just the {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} callback:

ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

Animating Layout Changes to ViewGroups

The property animation system provides the capability to animate changes to ViewGroup objects as well as provide an easy way to animate View objects themselves.

You can animate layout changes within a ViewGroup with the {@link android.animation.LayoutTransition} class. Views inside a ViewGroup can go through an appearing and disappearing animation when you add them to or remove them from a ViewGroup or when you call a View's {@link android.view.View#setVisibility setVisibility()} method with {@link android.view.View#VISIBLE}, android.view.View#INVISIBLE}, or {@link android.view.View#GONE}. The remaining Views in the ViewGroup can also animate into their new positions when you add or remove Views. You can define the following animations in a {@link android.animation.LayoutTransition} object by calling {@link android.animation.LayoutTransition#setAnimator setAnimator()} and passing in an {@link android.animation.Animator} object with one of the following {@link android.animation.LayoutTransition} constants:

You can define your own custom animations for these four types of events to customize the look of your layout transitions or just tell the animation system to use the default animations.

The LayoutAnimations sample in API Demos shows you how to define animations for layout transitions and then set the animations on the View objects that you want to animate.

The LayoutAnimationsByDefault and its corresponding layout_animations_by_default.xml layout resource file show you how to enable the default layout transitions for ViewGroups in XML. The only thing that you need to do is to set the android:animateLayoutchanges attribute to true for the ViewGroup. For example:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />  

Setting this attribute to true automatically animates Views that are added or removed from the ViewGroup as well as the remaining Views in the ViewGroup.

Using a TypeEvaluator

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 int, float, or a color, which are supported by the {@link android.animation.IntEvaluator}, {@link android.animation.FloatEvaluator}, and {@link android.animation.ArgbEvaluator} type evaluators.

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:

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);
    }
}

Note: 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 interpolated version of that depending on what interpolator that you are using. The interpolated fraction is what your {@link android.animation.TypeEvaluator} receives through the fraction parameter, so you do not have to take into account the interpolator when calculating animated values.

Using Interpolators

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.

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.

As an example, how the default interpolator {@link android.view.animation.AccelerateDecelerateInterpolator} and the {@link android.view.animation.LinearInterpolator} calculate interpolated fractions are compared below. The {@link android.view.animation.LinearInterpolator} has no effect on 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:

AccelerateDecelerateInterpolator

public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

LinearInterpolator

public float getInterpolation(float input) {
    return input;
}

The following table represents the approximate values that are calculated by these interpolators for an animation that lasts 1000ms:

ms elapsed Elapsed fraction/Interpolated fraction (Linear) Interpolated fraction (Accelerate/Decelerate)
0 0 0
200 .2 .1
400 .4 .345
600 .6 .8
800 .8 .9
1000 1 1

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.

Specifying Keyframes

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.

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:

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
rotationAnim.setDuration(5000ms);

For a more complete example on how to use keyframes, see the MultiPropertyAnimation sample in APIDemos.

Animating Views

The property animation system allow streamlined animation of View objects and offerse a few advantages over the view animation system. The view animation system transformed View objects by changing the way that they were drawn. This was handled in the container of each View, because the View itself had no properties to manipulate. This resulted in the View being animated, but caused no change in the View object itself. This led to behavior such as an object still existing in its original location, even though it was drawn on a different location on the screen. In Android 3.0, new properties and the corresponding getter and setter methods were added to eliminate this drawback.

The property animation system can animate Views on the screen by changing the actual properties in the View objects. In addition, Views also automatically call the {@link android.view.View#invalidate invalidate()} method to refresh the screen whenever its properties are changed. The new properties in the {@link android.view.View} class that facilitate property animations are:

To animate a property of a View object, such as its color or rotation value, all you need to do is create a property animator and specify the View property that you want to animate. For example:

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
For more information on creating animators, see the sections on animating with ValueAnimator and ObjectAnimator

Declaring Animations in XML

The property animation system lets you declare property animations with XML instead of doing it programmatically. The following Android classes have XML declaration support with the following XML tags:

Both <animator> ({@link android.animation.ValueAnimator}) and <objectAnimator> ({@link android.animation.ObjectAnimator}) have the following attributes:

android:duration
The number of milliseconds that the animation runs. The default is 300 ms.
android:valueFrom and android:valueTo
The values being animated between. These are restricted to numbers (float or int) and color values (such as #00ff00). They can be float, int, colors, or any kind of Object when creating animations programmatically.
android:valueType
Set to either "floatType" or "intType". The default is "floatType" unless you specify something else or if the valuesFrom and valuesTo values are colors.
android:startOffset
The delay, in milliseconds, before the animation begins playing (after calling {@link android.animation.ValueAnimator#start start()}).
android:repeatCount
How many times to repeat an animation. Set to "-1" to infinitely repeat or to a positive integer. For example, a value of "1" 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 "0", which means no repetition.
android:repeatMode
How an animation behaves when it reaches the end of the animation. android:repeatCount must be set to a positive integer or "-1" for this attribute to have an effect. Set to "reverse" to have the animation reverse direction with each iteration or "repeat" to have the animation loop from the beginning each time.

The objectAnimator ({@link android.animation.ObjectAnimator}) element has the additional attribute propertyName, that lets you specify the name of the property being animated. The objectAnimator element does not expose a target 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 unlike the underlying {@link android.animation.ObjectAnimator}, before calling {@link android.animation.ObjectAnimator#start start()}.

The set element ({@link android.animation.AnimatorSet}) exposes a single attribute, ordering. Set this attribute to together (default) to play all the animations in this set at once. Set this attribute to sequentially to play the animations in the order they are declared.

You can specify nested set tags to further group animations together. The animations that you want to group together should be children of the set tag and can define their own ordering attribute.

As an example, this XML code creates an {@link android.animation.AnimatorSet} object that animates x and y at the same time, then runs an animation that fades an object out:

<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>

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}.