LazyColumn Animations in Jetpack Compose (with Examples)

Jetpack Compose LazyColumn Animations

In this article, we’ll learn how to add animations to the LazyColumn in Jetpack Compose with examples.

Prerequisites:

For the purpose of this article, we’ll animate the items while performing the following operations:

  1. Shuffle the items
  2. Adding new items
  3. Removing existing items

First, create an empty Compose project and open MainActivity. Create a Composable called MyUI() and call it from the onCreate(). We’ll write our code in it.

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Column(
                        modifier = Modifier.fillMaxSize(),
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
fun MyUI() {

}

1. Shuffle Animation:

Just below the MyUI(), create a data class called ListItem. We need it for storing the items.

data class ListItem(val id: Int, val name: String)

It takes two parameters:

  • id – It is a unique value required for animating the items.
  • name – Name of the item.

Jetpack Compose provides animateItemPlacement() modifier. It automatically animates the item’s placement.

@ExperimentalFoundationApi
fun Modifier.animateItemPlacement(
    animationSpec: FiniteAnimationSpec<IntOffset> = spring(
        stiffness = Spring.StiffnessMediumLow,
        visibilityThreshold = IntOffset.VisibilityThreshold
    )
): Modifier

The animationSpec parameter helps us to customize the animation. Let’s see how to use the modifier.

Add the following code to the MyUI().

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyUI1() {
    var list = remember { mutableStateListOf<ListItem>() }

    LazyColumn(
        contentPadding = PaddingValues(all = 8.dp), // margin to the whole layout
        verticalArrangement = Arrangement.spacedBy(space = 8.dp), // gap between items
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        items(
            items = list,
            key = { listItem ->
                listItem.id
            }
        ) { listItem ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .animateItemPlacement() // animates the item placement
            ) {
                Text(
                    modifier = Modifier.padding(all = 8.dp),
                    text = listItem.name
                )
            }
        }

        item {
            Button(onClick = { list.shuffle() }) {
                Text("Shuffle")
            }
        }
    }

    LaunchedEffect(key1 = Unit) {
        list.add(ListItem(id = 1, name = "Iron Man"))
        list.add(ListItem(id = 2, name = "Thor: Ragnarok"))
        list.add(ListItem(id = 3, name = "Captain America: Civil War"))
        list.add(ListItem(id = 4, name = "Doctor Strange"))
        list.add(ListItem(id = 5, name = "The Incredible Hulk"))
        list.add(ListItem(id = 6, name = "Ant-Man and the Wasp"))
    }
}

data class ListItem(val id: Int, val name: String)

Output:

shuffle animation

Let’s understand it.

First, we created the list object and added items in the launched effect block. The block gets called when the app is launched the first time.

Next, we added LazyColumn. The items are added using the items() method. It takes two parameters:

  • items – It is the list.
  • key – It is used to identify the items. We passed our id values. The animation is based on these keys.

In the card layout, we added animateItemPlacement() modifier. It is responsible for animating the items. In the button’s onClick block, the items of the list are reordered.

Let’s change the animation duration. In the above code, add the tween() method to the animationSpec parameter.

Card(
    modifier = Modifier
        .fillMaxWidth()
        .animateItemPlacement(
            animationSpec = tween(durationMillis = 1000)
        )
) {
    Text(
        modifier = Modifier.padding(all = 8.dp),
        text = listItem.name
    )
}

Output:

shuffle animation duration

The modifier automatically animates the placement of the new items and deletion of the old items. Let’s look at them.

2. Animation while Adding New Items:

Let’s add some items in the button’s onClick block.

Button(
    onClick = {
        list.add(2, ListItem(id = list.size + 1, name = "New Movie")) // add the item
    }
) {
    Text("Add New Movie") // change the button text
}

Output:

add animation

Note: The id should be unique. Do not pass the same value to multiple items.

3. Animation while Removing Items:

Remove elements using the removeAt() method.

Button(
    onClick = {
        list.removeAt(2) // remove the item
    }
) {
    Text("Remove Movie") // change the button text
}

Output:

Remove animation

This is all about the LazyColumn item animations in Jetpack Compose. I hope you have learned something new. If you have any doubts, leave a comment below.

Related Articles:


References:

Leave a Comment