Playing Animators Together

If all you need to do is kick off a few animations at the same time, then your job is simple: Call start() on them all at the same time. They will all animate in sync with one another.

For more sophisticated animation choreography, this will not do the trick. For example, to complete the illusion of a sunset, it would be nice to show the sky turning from orange to a midnight blue after the sun goes down.

This can be done by using an AnimatorListener, which tells you when an animation completes. So you could write a listener that waits until the end of the first animation, at which time you can start the second night sky animation. But this is a huge hassle and requires a lot of listeners. It is much easier to use an AnimatorSet.

First, build out the night sky animation and delete your old animation start code.

Listing 31.12  Building night animation (MainActivity.kt)

private fun startAnimation() {
    val sunYStart = sunView.top.toFloat()
    val sunYEnd = skyView.height.toFloat()

    val heightAnimator = ObjectAnimator
        .ofFloat(sunView, "y", sunYStart, sunYEnd)
        .setDuration(3000)
    heightAnimator.interpolator = AccelerateInterpolator()

    val sunsetSkyAnimator = ObjectAnimator
        .ofInt(skyView, "backgroundColor", blueSkyColor, sunsetSkyColor)
        .setDuration(3000)
    sunsetSkyAnimator.setEvaluator(ArgbEvaluator())

    val nightSkyAnimator = ObjectAnimator
        .ofInt(skyView, "backgroundColor", sunsetSkyColor, nightSkyColor)
        .setDuration(1500)
    nightSkyAnimator.setEvaluator(ArgbEvaluator())

    heightAnimator.start()
    sunsetSkyAnimator.start()
}

And then build and run an AnimatorSet.

Listing 31.13  Building an animator set (MainActivity.kt)

private fun startAnimation() {
    ...
    val nightSkyAnimator = ObjectAnimator
        .ofInt(skyView, "backgroundColor", sunsetSkyColor, nightSkyColor)
        .setDuration(1500)
    nightSkyAnimator.setEvaluator(ArgbEvaluator())

    val animatorSet = AnimatorSet()
    animatorSet.play(heightAnimator)
        .with(sunsetSkyAnimator)
        .before(nightSkyAnimator)
    animatorSet.start()
}

An AnimatorSet is nothing more than a set of animations that can be played together. There are a few ways to build one, but the easiest way is to use the play(Animator) function you used above.

When you call play(Animator), you get an AnimatorSet.Builder, which allows you to build a chain of instructions. The Animator passed into play(Animator) is the subject of the chain. So the chain of calls you wrote here could be described as, Play heightAnimator with sunsetSkyAnimator; also, play heightAnimator before nightSkyAnimator. For complicated AnimatorSets, you may find it necessary to call play(Animator) a few times, which is perfectly fine.

Run your app one more time and savor the soothing sunset you have created. Magic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.195.110