androidkotlinanimationandroid-jetpack-composelazycolumn

How Can I Call Another Composable within an Item in a Lazy Column with Animation?


I'm still learning compose/kotlin and have come up with a problem that seems very common, but I can't find a solution.

I have a LazyColumn with animation--that works great for making additions and subtractions from the LazyColumn visible and attractive. But I want to have a very complicated items. They are very unwieldy, so I naturally want to have them in their own function.

But when I move the item content to a separate composable function, the inner function doesn't know how to deal with animateItemPlacement().

Here is my (simplified) code for the composable function with the LazyColumn

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LazyColumnAnimExample(
    stringList: List<String>,
    modifier: Modifier
) {
    LazyColumn(
        modifier = modifier
            .padding(top = 62.dp)
    ) {
        stringList.forEach { str ->
            item(key = str) {
                ComplicatedItemDraw(str)
            }
        }
    }
}

And here is the function (greatly simplified) that draws each item

@Composable
fun ComplicatedItemDraw(text: String) {
    Text(
        text = text,
        style = MaterialTheme.typography.headlineLarge,
        modifier = Modifier
            .animateItemPlacement()  // error
    )
}

The error message is "Unresolved reference: animateItemPlacement"

There has to be a way around this--probably something simple.


Solution

  • animateItemPlacement is a function defined in LazyItemScope interface, so for you to be able to use it in your function, it has to be an extension function of that interface:

    @Composable
    fun LazyItemScope.ComplicatedItemDraw(text: String) {
        Text(text, modifier = Modifier.animateItemPlacement())
    }
    

    This however means that you won't be able to use ComplicatedItemDraw outside of LazyList. Probably a better solution and a best practice, is to define Modifier parameter on your composable and pass animateItemPlacement() from your item {} like this:

    @Composable
    fun Example() {
        LazyColumn {
            item {
                ComplicatedItemDraw("", Modifier.animateItemPlacement())
            }
        }
    }
    
    @Composable
    fun ComplicatedItemDraw(text: String, modifier: Modifier = Modifier) {
        Text(text, modifier = modifier)
    }