Android Animation Tutorial with Kotlin

In this Android animation tutorial, you will learn how to use property animations to make a fun, beautiful user interface. By Kevin D Moore.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Animation Options

Animations are not one-trick ponies that simply stop and go. They can loop, reverse, run for a specific duration, etc.

In Android, you can use the following methods to adjust an animation:

  • repeatCount — specifies the number of times the animation should repeat after the initial run.
  • repeatMode — defines what this animation should do when it reaches the end.
  • duration — specifies the animation’s total duration.

Open up FlyThereAndBackAnimationActivity.kt, and add the following to onStartAnimation().

// 1
val animator = ValueAnimator.ofFloat(0f, -screenHeight)

animator.addUpdateListener {
  val value = it.animatedValue as Float
  rocket.translationY = value
  doge.translationY = value
}

// 2
animator.repeatMode = ValueAnimator.REVERSE
// 3
animator.repeatCount = 3

// 4
animator.duration = 500L
animator.start()

In here, you:

In this case, you set it to REVERSE because you want the rocket to take off and then go back to the same position where it started. Just like SpaceX! :]

  1. Create an animator, as usual.
  2. You can set the repeatMode to either of the following:
    • RESTART — restarts the animation from the beginning.
    • REVERSE — reverses the animation’s direction with every iteration.

    In this case, you set it to REVERSE because you want the rocket to take off and then go back to the same position where it started. Just like SpaceX! :]

  3. …Except you’ll do it twice.
  4. Set a duration and start the animation, as usual.

Note: So why does the third section specify a repeat count of three? Each up-and-down motion consumes two repetitions, so you need three to bring Doge back to earth twice: one to land the first time, and two to launch and land again. How many times would you like to see Doge bounce? Play around with it!

Note: So why does the third section specify a repeat count of three? Each up-and-down motion consumes two repetitions, so you need three to bring Doge back to earth twice: one to land the first time, and two to launch and land again. How many times would you like to see Doge bounce? Play around with it!

Run the app. Select Fly there and back (Animation options) in the list. A new screen is opened. Tap on the screen.

there-and-back

You should see your rocket jumping like a grasshopper! Take that, Elon Musk. :]

Declaring Animations in XML

You’ve made it to the best part of this tutorial. In this final section, you’ll learn how to declare once and use everywhere — yes, that’s right, you’ll be able to reuse your animations with impunity.

By defining animations in XML, you allow reuse of animations throughout your code base.

Defining animations in XML bears some resemblance to composing view layouts.

The starter project has an animation XML in res/animator named jump_and_blink.xml. Open the file in the editor, you should see this:

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

The following XML tags are available to you:

  • set — the same as AnimatorSet.
  • animator — the same as ValueAnimator.
  • objectAnimator — you guessed correctly; it stands for ObjectAnimator.

When using an AnimatorSet in XML, you nest the ValueAnimator and ObjectAnimator objects inside it, similar to how you nest View objects inside ViewGroup objects (RelativeLayout, LinearLayout, etc.) in layout XML files.

Replace the contents of jump_and_blink.xml with the following code:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:ordering="together">
    
  <objectAnimator
    android:propertyName="alpha"
    android:duration="1000"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:interpolator="@android:interpolator/linear"
    android:valueFrom="1.0"
    android:valueTo="0.0"
    android:valueType="floatType"/>

  <objectAnimator
    android:propertyName="translationY"
    android:duration="1000"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:interpolator="@android:interpolator/bounce"
    android:valueFrom="0"
    android:valueTo="-500"
    android:valueType="floatType"/>
</set>

Here you declare a root element, set tag. Its ordering attribute can be either together or sequential. It’s together by default, but you may prefer to specify it for clarity. The set tag has two child XML tags, each of which is an objectAnimator.

Take a look at the following attributes of objectAnimator:

  • android:valueFrom and android:valueTo — specify start and end values like you did when you created an instance of ObjectAnimator.
  • android:valueType — value type; either floatType or intType.
  • android:propertyName — the property you want to animate without the set part.
  • android:duration — duration of the animation.
  • android:repeatCount — the same as with setRepeatCount.
  • android:repeatMode — the same as with setRepeatMode.
  • android:interpolator — specify interpolator; it usually starts with @android:interpolator/. Start typing this and Android Studio will show all available interpolators under autocomplete options.
  • You can’t specify your target object here, but you can do it later in Kotlin.

In the last block, you added two instances of objectAnimator to the AnimatorSet, and they will play together. Now, it’s time to use them.

Go to XmlAnimationActivity.kt and add the following code to onStartAnimation():

  // 1
  val rocketAnimatorSet = AnimatorInflater.loadAnimator(this, R.animator.jump_and_blink) as AnimatorSet
  // 2
  rocketAnimatorSet.setTarget(rocket)
  
  // 3
  val dogeAnimatorSet = AnimatorInflater.loadAnimator(this, R.animator.jump_and_blink) as AnimatorSet
  // 4
  dogeAnimatorSet.setTarget(doge)

  // 5
  val bothAnimatorSet = AnimatorSet()
  bothAnimatorSet.playTogether(rocketAnimatorSet, dogeAnimatorSet)
  // 6
  bothAnimatorSet.duration = DEFAULT_ANIMATION_DURATION
  bothAnimatorSet.start()

In the above code, you’re doing a few things:

  1. First, you load AnimatorSet from R.animator.jump_and_blink file, just like you normally would to inflate a view layout.
  2. Then you set rocket as the target for just-loaded animator.
  3. Load the animator from the same file once again.
  4. Rinse and repeat for doge object.
  5. Now you create a third AnimatorSet and set it up to play the first two simultaneously.
  6. Set the duration for the root animator and start.
  7. Whew! Rest just a little bit :]

Build and run. Select Jump and blink (Animations in XML) in the list. Tap to see your handiwork.

jump-n-blink

You should see Doge jumping, disappearing and then returning back to the ground safely :]

Where To Go From Here?

You can download the completed project by clicking on the Download Materials button at the top or bottom of the tutorial.

During this tutorial you:

  • Created and used property animations with ValueAnimator and ObjectAnimator.
  • Set up the time interpolator of your choice for your animation.
  • Animate position, rotation and color for View.
  • Combined animations together.
  • Used the spectacular ViewPropertyAnimator with the help of animate().
  • Repeated your animation.
  • Defined the animation in XML for reuse across the project.

Basically, you just gained Android animation super-powers.

If you’re hungry for more, check out the available time interpolators in Android’s documentation (see Known Indirect Subclasses). If you’re not happy with either of them, you can create your own. You can also set Keyframes for your animation to make them very sophisticated.

Android has other animation systems like View animations and Drawable Animations. You can also make use of Canvas and OpenGL ES APIs to create animations. Stay tuned :]

I hope you enjoyed the Introduction to Android Animations tutorial. Chime in with your questions, ideas and feedback in the forums below!