How to apply stacking animation to composables within Column composable in jetpack compose?

43 Views Asked by At

I have a list of languages wihtin Column() composable. I want to apply stacking animation to all composables within Column() composable. I wrote some code for the same and its working partially. It's animating all RadioButtonChip() composables at once. But i want some delay in animation for each RadioButtonChip() composable so it gives stacking animation feel.

 val animateOffsetY = remember { Animatable(300f) }

    LaunchedEffect(Unit) {
        languages.forEachIndexed { index, _ ->
            delay(index.toLong() * 200)
            animateOffsetY.animateTo(0f, animationSpec = tween(500))
        }
    }

    Column(
        modifier = modifier.fillMaxSize()
    ) {
        languages.forEachIndexed { index, language ->
            RadioButtonChip(
                modifier = Modifier
                    .fillMaxWidth(0.5f)
                    .offset { IntOffset(0, animateOffsetY.value.roundToInt()) },
                languageName = language.languageName
            )
        }
    }
1

There are 1 best solutions below

0
Thracian On BEST ANSWER

It's expected behavior because you have only one Animatable. If you have list of Animatables each RadioButtonChip will have their individual animation such as

@Preview
@Composable
fun AnimationTest() {

    val languages = remember {
        List(10) {
            it
        }
    }

    
    val animatableList = remember {
        List(languages.size) {
            Animatable(300f)
        }
    }
    animatableList.forEachIndexed { index, animatable ->
        LaunchedEffect(Unit) {
            delay(index.toLong() * 500)
            animatable.animateTo(0f, animationSpec = tween(1500))
        }
    }

    Column(modifier = Modifier.fillMaxSize().border(2.dp, Color.Red)) {

        languages.forEachIndexed { index, language ->
            Text(
                text = "Row $language",
                modifier = Modifier
                    .offset { IntOffset(0, animatableList[index].value.roundToInt()) }
                    .fillMaxWidth()
                    .padding(8.dp)
            )
        }
    }
}