Exploring Jetpack Compose LazyList animations
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:
- We define a list of
Item
s, this will be the content of our list. We use theList
factory method, which calls our item factory to generate the items. We then convert this to aMutableStateList
— any changes to the list will trigger a recomposition of any composables using the list. - Next we define a
Column
for the content, as we want to display 2 main sections in this sample app, stacked vertically. - The first section is the
LazyColumn
, which we set to take all available space by using aweight(1f)
modifier. - Inside the
LazyColumn
we use theitemsIndexed
extension function — this will loop over the items in our list so that we can build the corresponding composable. - For each item, we define a
key
— this is important when the item content is dynamic, so that theLazyColumn
maintains each item state. - 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 currentItem
. - Here we define the 2nd section or our screen, a
Row
. - Inside this row we have a
Button
that shuffles the content of the list. Because we used aMutableStateList
for the items, mutating the list will trigger a recomposition. - We have next another
Button
that adds a new item to the list, at a random position. - 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 you run this one, you’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 below. I hope you found this useful, and I’ll see you on the next one!