Android Development – More Animations, Part 2

By | June 10, 2010

In this final part of this series, I’ll demonstrate how to combine animations and sprinkle some interpolator goodness in the animation definition file. We’ll be picking up where we left off in Part 1, so go there to review if you have to.

Animation Sets

The way to combine animations in Android is by using an AnimationSet. An animation set is treated as a single unit in code, allowing you to apply the entire set to whatever element it is you want to animate. You can nest your animation sets as well. For our example, we will simply be combining two different animations into one. To start out, we need to modify our current layout by adding two additional text views which we will use to demonstrate our combined animations. The final XML for our layout appears below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal">
    <TextView
        android:id="@+id/firstTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="Wow"
        android:textSize="42sp" />
    <TextView
        android:text="Some"
        android:id="@+id/secondTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="42sp"></TextView>
    <TextView
        android:text="Text"
        android:id="@+id/thirdTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="42sp"></TextView>
    <TextView
        android:text="More Text"
        android:id="@+id/fourthTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="42sp"></TextView>
    <TextView
        android:text="And Still More"
        android:id="@+id/fifthTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="42sp"></TextView>
</LinearLayout>

Now we need to add two new animations to our project the same way we did in Part 1. The only difference is that this time we will need to select “set” as our base element, as shown below.

rootElement

For our example, we will be combining the scale and rotate animations, and then the translate and alpha animations. As such, we name our two new animation files “scalerotate.xml” and “translatealpha.xml”.

Once we have our animation set files created and opened up, all we have to do is add the animations we want into the <set> tag. Our scale rotate animation set appears below.

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android">

    <rotate
        android:fromDegrees="359"
        android:toDegrees="0"
        android:duration="3000"
        android:pivotX="50%"
        android:pivotY="50%" />

    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="2.0"
        android:toYScale="2.0"
        android:duration="3000"></scale>
</set>

We covered the rotate animation in Part 1. The scale rotation animates the target by making it larger or smaller based on its configuration. For our example above, we are expanding the size of the target text from its original size up to twice its size, over the course of three seconds. The translate alpha animation set appears below.

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:fromXDelta="-200%"
        android:toXDelta="0%"
        android:fromYDelta="200%"
        android:toYDelta="0%"
        android:duration="3000"
        android:zAdjustment="top" />

    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="6000" />
</set>

Nothing new here, as we have covered both of these animations in Part 1. That’s all it takes to combine animations into one unit. Before we see our finished product however, it’s time to do some sprinkling.

Interpolators

I covered interpolators briefly in my bounce animation post, from a code perspective. Here we will add them into the animation definition file instead. We’ll start by adding an anticipate overshoot interpolator to the rotate animation in our scale-rotate animation set. Our modified rotate animation appears below.

<rotate
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:fromDegrees="359"
android:toDegrees="0"
android:duration="3000"
android:pivotX="50%"
android:pivotY="50%" />

By adding the “android:interpolator” attribute, we’ve associated the indicated interpolator with our rotate animation. For the scale animation in the same set, we’ll add an accelerate interpolator.

<scale
android:interpolator="@android:anim/accelerate_interpolator"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="2.0"
android:toYScale="2.0"
android:duration="3000"></scale>

Right away we notice that we can associate different interpolators with different animations in our set. We could also specify one interpolator for the entire set. For our translate-alpha animation set, we sprinkle in the interpolator at the animation set level, as below.

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator">

    <translate
        android:fromXDelta="-200%"
        android:toXDelta="0%"
        android:fromYDelta="200%"
        android:toYDelta="0%"
        android:duration="3000"
        android:zAdjustment="top" />

    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="6000" />
</set>

As you can see, we’ve added an accelerate decelerate interpolator to this set.

The Code

The final part is to load up our new animation sets and apply them to the two new text views we introduced at the beginning. The code is the same for this as it was when we were loading single animations in Part 1, and appears below.

private void RunAnimations() {
    Animation a = AnimationUtils.loadAnimation(this, R.anim.alpha);
    a.reset();
    TextView tv = (TextView) findViewById(R.id.firstTextView);
    tv.clearAnimation();
    tv.startAnimation(a);

    a = AnimationUtils.loadAnimation(this, R.anim.translate);
    a.reset();
    tv = (TextView) findViewById(R.id.secondTextView);
    tv.clearAnimation();
    tv.startAnimation(a);

    a = AnimationUtils.loadAnimation(this, R.anim.rotate);
    a.reset();
    tv = (TextView) findViewById(R.id.thirdTextView);
    tv.clearAnimation();
    tv.startAnimation(a);

    a = AnimationUtils.loadAnimation(this, R.anim.translatealpha);
    a.reset();
    tv = (TextView) findViewById(R.id.fourthTextView);
    tv.clearAnimation();
    tv.startAnimation(a);

    a = AnimationUtils.loadAnimation(this, R.anim.scalerotate);
    a.reset();
    tv = (TextView) findViewById(R.id.fifthTextView);
    tv.clearAnimation();
    tv.startAnimation(a);
}

The Finished Product

Once you’ve laced all this together, run the app, and you should see something like the video below.