page.title=Animation @jd:body

In this document

  1. Property Animation
    1. Animating with ValueAnimator
    2. Animating with ObjectAnimator
    3. Using the TypeEvaluator
    4. Using interpolators
    5. Specifying keyframes
    6. Choreographing multiple animations with AnimatorSet
    7. Declaring animations in XML
  2. View Animation
    1. Tween animation
    2. Frame animation

Key classes

  1. ValueAnimator
  2. ObjectAnimator
  3. TypeEvaluator

Related samples

  1. API Demos

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: property animation and view animation. You can use whichever system that matches your needs, but use only one system for each object that you are animating.

Property Animation

Introduced in Android 3.0, the property animation system allows you to animate object properties of any type. int, float, 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.

The property animation system allows you to define many aspects of an animation, such as:

Most of the property animation system's features can be found in {@link android.animation android.animation}. Because the Animating with ValueAnimator for more information.

  • {@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 Animating with ObjectAnimator for more information.
  • {@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 Choreographing multiple animations with Animator Sets for more information.
  • Evaluators

    If you are animating an object property that is not an int, float, 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.

    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 Using a TypeEvaluator for more information on how to write a custom evaluator.

    Interpolators

    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.

    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 Interpolators for more information on how to write a custom interpolator.

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

    How the property animation system calculates animated values

    When you call {@link android.animation.ValueAnimator#start start()} to begin an 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%. The Animator then calls the {@link android.animation.TimeInterpolator} that is currently set, to calculate an eased fraction, 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 easing). The eased fraction is the final value that is used to animate the property.

    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.

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

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

    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:

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

    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 that object's property (as a String) that you want to animate:

    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:

    Using the 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 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 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 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:

    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/Eased fraction (Linear) Eased 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(.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);
     
    
    For a more complete example on how to use keyframes, see the MultiPropertyAnimation sample in APIDemos.

    Choreographing multiple animations with Animator Sets

    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.

    Declaring animations in XML

    As with view animation, 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:

    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.
    android:valueFrom and android:valueTo
    The values being animated between. These are restricted to numbers (float or int) in XML. They can be float, int, or any kind of Object when creating animations programmatically.
    android:valueType
    Set to either "floatType" or "intType".
    android:startDelay
    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" for infinite repeating 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".
    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, 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 (together is the default ordering when nothing is specified), 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}.

    View Animation

    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.

    Tween Animation

    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.

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

    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.

    The animation XML file belongs in the res/anim/ directory of your Android project. The file must have a single root element: this will be either a single <alpha>, <scale>, <translate>, <rotate>, interpolator element, or <set> element that holds groups of these elements (which may include another <set>). By default, all animation instructions are applied simultaneously. To make them occur sequentially, you must specify the startOffset attribute, as shown in the example below.

    The following XML from one of the ApiDemos is used to stretch, then simultaneously spin and rotate a View object.

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

    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.

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

    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.

    With this XML saved as hyperspace_jump.xml in the res/anim/ directory of the project, the following code will reference it and apply it to an {@link android.widget.ImageView} object from the layout.

    ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
    Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
    spaceshipImage.startAnimation(hyperspaceJumpAnimation);
    

    As an alternative to startAnimation(), you can define a starting time for the animation with {@link android.view.animation.Animation#setStartTime(long) Animation.setStartTime()}, then assign the animation to the View with {@link android.view.View#setAnimation(android.view.animation.Animation) View.setAnimation()}.

    For more information on the XML syntax, available tags and attributes, see Animation Resources.

    Note: 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 will occur if the animation exceeds the bounds of the parent View.

    Frame Animation

    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.

    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 res/drawable/ directory of your Android project. In this case, the instructions are the order and duration for each frame of the animation.

    The XML file consists of an <animation-list> element as the root node and a series of child <item> 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:

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

    This animation runs for just three frames. By setting the android:oneshot attribute of the list to true, it will cycle just once then stop and hold on the last frame. If it is set false then the animation will loop. With this XML saved as rocket_thrust.xml in the res/drawable/ 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:

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

    It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() 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 {@link android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()} method in your Activity, which will get called when Android brings your window into focus.

    For more information on the XML syntax, available tags and attributes, see Animation Resources.