Introduction to Animation in Jetpack Compose

Anang Kurniawan
Jan 7 · 7 min read

Animation has been a complex task when it comes to implementing our code. But it has changed when Jetpack Compose introduces its animation library.

Animation in jetpack compose

Jetpack Compose has introduced its animation library. You can see it in its official documentation. It has covered all libraries and gives us a guide for choosing which libraries are suitable for our use case, as you can see in the flowchart below.

Great flowchart to help us choosing animation library in jetpack compose by Google

It gives us an easy way to choose what library we should use that is suitable for our use case. For example, if we just need to animate content in a layout and animate its enter/exit transition, we can use AnimatedVisibility and so on.

In the official documentation, we can see that the APIs have been separated into high-level and Low-Level APIs, which we will discuss in this article. Also, we will discuss customizing our animation params using AnimationSpec.

High-Level APIs

These APIs are designed to be suitable with several common animation patterns. And had been aligned with the best practices of Material Design Motion.

High-Level APIs contains:

  • AnimatedVisibility (experimental)
  • animateContentSize
  • Crossfade

AnimatedVisibility animates the visibility or appearance and disappearance of its content.

Let’s take a look at the snippet below:

As you can see, we will animate the visibility of a Text inside a Box. You can see the result below:

We can also customize the enter and exit animation using predefined enter and exit transitions.

EnterTransition

ExitTransition

let’s try to use slideIn and slideOut for exit and enter transition

You can see the result below:

Also, we can combine the enter and exit transition using operator +. For example, when combining fadeIn() and fadeOut() in our enter and exit transition.

Result

As you can see it adds a slight fade effect at end of the enter and exit transition.

By default AnimatedVisibility using fadeIn() + expandHorizontally() as enterTransition, and fadeOut() + shrinkHorizontally() as exitTransition.

We can use animateContentSize() if we want to animate the size of our layout; animateContentSize() used as modifier. As you can see at the snippet below:

We are going to animate the size of the Box according to the length of the text. See the result below:

Crossfade animate the transition between two layouts using crossfade animation. Let’s try implementing crossfade.

Result

That’s all in the High-Level APIs. Let’s move to the Low-Level APIs in Jetpack Compose Animation.

Low-Level APIs

Low-Level APIs are the foundation of all High-Level APIs that we already discuss in the previous section. Low-Level APIs contains

  • animate*AsState
  • Animateable
  • updateTransition
  • rememberInfiniteTransition
  • TargetBasedAnimation

animate*AsState only animate a single value that makes this API the simplest API in jetpack animation APIs. We can animate these values in animate*AsState

  • Float
  • Color
  • Dp
  • Size
  • Bounds
  • Offset
  • Rect
  • Int
  • IntOffset
  • IntSize

If you want to animate other data types that are not supported yet in animate*AsState, try using TwoWayConverter.

We can use this API in any condition as long it’s using the supported value. For example, we’re going to make a simple animation that will move the button forward and backward using animateDpAsState.

updateTransition manages multiple values of animations and runs them simultaneously in multiple states. In short, it combines more than one animate*AsState that runs simultaneously.

For example, you can see the implementation in the snippet below:

We are going to animate four values simultaneously, it is contentColor, contentPosition, contentSize, and iconColor . And here’s the result:

Same as the updateTransition, rememberInfiniteTransition also manages multiple animation values that runs simultaneously. But it runs right after entering the composition and doesn’t stop unless removed.

Implement rememberInfiniteTransition is just like implementing the updateTransition but, we don’t need to create a state and replace it with targetValue and initialValue as params. Let’s see on the snippet below:

And here’s the result:

AnimationSpecs

We have discussed all High-Level APIs and Low-Level APIs. But how do we customize the animation? Let’s discuss in this section.

Jetpack Compose has allowed us to customize the animation APIs using AnimationSpecs. AnimationSpecs is used as a parameter in animation APIs, and you can use different AnimationSpecs to create various animations.

The first AnimationSpecs we are going to discussis Spring. Spring will create a bounce effect in our animation. It takes two parameters; dampingRatio and stiffness.

dampingRatio is the parameter to define how bouncy the Spring could be. Here are some pre-defined dampingRatio that we can use:

  • DampingRatioHighBouncy
  • DampingRatioMediumBouncy
  • DampingRatioLowBouncy
  • DampingRatioNoBouncy

The default value is DampingRatioNoBouncy

stiffness. The speed of the spring animation to move toward the end value, we can use pre-defined stiffness that Jetpack Compose has provided.

  • StiffnessHigh
  • StiffnessMedium
  • StiffnessLow
  • StiffnessVeryLow

the default value is StiffnessMedium

Let’s see how we implemented spring as a spec in our animation.

For example, when we are using DampingRatioHighBouncy and StiffnessMedium

Tween is the spec if you want to manipulate the speed of the animation. It animates between the start and end value over the durationMilis and delayMilis params.

With tween, you can easily manage when your animation should start or set the duration, and also you can manipulate its movement speed using an easing curve.

There are several pre-defined easing curves that you can implement such as:

  • FastOutSlowInEasing
  • LinearOutSlowInEasing
  • FastOutLinearEasing
  • LinearEasing
  • CubicBezierEasing

Or, if you have a better understanding of creating an easing curve, you can create your easing curve as described in the official documentation. The default value of the easing curve in tween is FastOutSlowInEasing. And for the duration is 300ms.

In the above example, we are using FastOutLinearEasing in every entry and exit animation so you can see the tween better.

KeyFrame gives you more control over the animation. With KeyFrame you can specify easing at the specific timestamp in the duration of the animation.

Repeatable will run your animation repeatedly until it reaches the iteration count. To implement repeatable as a spec, we need to specify these three params:

  • iterations (how many times the animation should repeat)
  • animations (animation that will be repeated, you can use the duration based animations such as tween, keyframe, and snap)
  • repeatMode (how the animation should repeat from start (Restart) or from the end (Reverse))

In the above example, we are using repeatable with 3 iterations; tween animation, and Reverse as repeatMode. you can see the result below:

Now let’s try the RepeatMode.Restart

Just like the repeatable but without the iterations, so it will repeat infinitely.

We are using Reverse as RepeatMode

snap will skip the animation to the end value. You can specify delayMilis in the parameter to delay the start of your animation.

Conclusion

That’s all we have discussed all animation in jetpack compose. And to close the discussion, I can say that implementing animation in jetpack compose is relatively easy and fun.

All we need has been defined in the Low-Level to High-Level APIs. We also can easily customize our animation using AnimationSpecs. And Google has done an excellent job by providing complete documentation with examples to implement it more effortlessly.

You can find all the result of our research about jetpack compose in my GitHub repo:

References

About The Author

I am an Android Developer who loves the world of arts. I work as an Android Developer, but sometimes I do a design challenge with my friends to fill my spare time.

LinkedIn Medium Dribbble Twitter Instagram

Sampingan Tech

The stories behind the code