Exploring Jetpack Compose LazyList Animations

Bring some delight to your lists with playful animations

Introduction

With the release of Jetpack Compose 1.2.0-alpha03 we have access to a much requested feature: animations in lazy lists when the collection of items is updated. In this short article we’ll learn how to use this feature.

The sample project

First we’ll create a simple sample project using LazyColumn without the items animation to see how it worked until now.

To keep it simple, our list will have a set of boxes with a label that will identify each box; let’s see how we define these items:

This is a simple composable, so there is not much to describe here. If you run this preview you’ll get this outcome:

Now that we have our basic block for the list, it’s time to create the list proper. We will define a data class to represent our data, which we will name Item, and we’ll also define a factory method that will generate a new Item based on its id. Let’s see this part first:

As described above, we have a simple data class to represent the contents of our list, with just 3 properties: an id to uniquely identify each item, a label and a color that we will use for the background.

We then define a factory method, and per Kotlin convention, we give this factory method the same name as the object it generates, which takes the item id and builds a ListItem assigning it a color from a set of colors.

Now that we have our data class and the factory, we can go ahead and implement our list:

Let’s go over this:

  1. We define a list of Items, this will be the content of our list. We use the List factory method, which calls our item factory to generate the items. We then convert this to a MutableStateList — any changes to the list will trigger a recomposition of any composables using the list.

  2. Next we define a Column for the content, as we want to display 2 main sections in this sample app, stacked vertically.

  3. The first section is the LazyColumn, which we set to take all available space by using a weight(1f) modifier.

  4. Inside the LazyColumn we use the itemsIndexed extension function — this will loop over the items in our list so that we can build the corresponding composable.

  5. For each item, we define a key — this is important when the item content is dynamic, so that the LazyColumn maintains each item state.

  6. The itemsIndexed extension takes a lambda that receives 2 arguments, the current index (which we are not using) and the item at this index. With this we build our composable for the current Item.

  7. Here we define the 2nd section or our screen, a Row.

  8. Inside this row we have a Button that shuffles the content of the list. Because we used a MutableStateList for the items, mutating the list will trigger a recomposition.

  9. We have next another Button that adds a new item to the list, at a random position.

  10. And finally we have a 3rd button that removes an item from the list, the one with the highest id.

If we ran this code, we get this:

And if we shuffle, add or remove items, we can see that the list updates abruptly:

Animating the list updates

To animate the list updates all we need to do is add 1 single line of code. When we add our items to the LazyColumn we use a Modifier to specify how to render our elements in the list; to enable list animations, all we have to do is add the modifier animateItemPlacement — it’s as simple as that. With this change, our LazyColumn becomes

And if we run this code, this is the result:

A definitive improvement, and all it took was adding a single line of code.

Changing the animation

The animateItemPlacement modifier takes an optional animation spec — the default looks pretty nice, but we can define our own animation spec if we prefer to customize it. While you could go pretty fancy here, for this article we will simply show how you can specify your own animation, in this case, we’ll replace it with a tween with a duration of 500ms:

And if we run this one, we’ll see a more subtle change when the list updates, the animation is slightly longer and slows down as it runs:

Conclusion

In this article we learnt how to use the new animateItemPlacement modifier to animate items in a LazyColumn or LazyRow. It’s worth of note that this feature is still experimental and subject to change, and it currently does not support LazyVerticalGrid, but it’s a great starting point to make updating lists feel more natural and engaging.

The full code for this sample is available in this gist.