LazyColumn animateItemPlacement doesn't work

216 Views Asked by At

I have a problem, animateItemPlacement in my LazyColumn simply doesn't work, code:

val laps = stopWatchViewModel.getLapsStates().collectAsState(initial = emptyList())
LazyColumn(
    modifier = Modifier
        .fillMaxSize()
        .padding(start = 52.dp, end = 52.dp)
) {
    items(items = laps.value, key = {lap -> lap.id}) { lap ->
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 12.dp, bottom = 12.dp)
                .animateItemPlacement(
                    animationSpec = tween(durationMillis = 250)
                ),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(text = lap.lap, color = Color(0xff383838), fontSize = 20.sp)
            Text(text = lap.lapTime, color = Color(0xff808080), fontSize = 20.sp)
            Text(text = lap.totalTime, color = Color(0xfff7f7f7), fontSize = 20.sp)
        }
    }
}

I tried to use key = { it }(it gives an exception), tried to use key = { it.id }, tried to use key = {lap -> lap.id}. It simply doesn't want to work, but keys are unic. Also i tried to change container to the box or card. This is project on git: (https://github.com/BRBXGIT/AlarmApp). Thanks in advance

1

There are 1 best solutions below

0
Егор Сауткин On BEST ANSWER

Finally i understand how to do this animation. The trick is that now animation of inserting or deleting something from LazyColumn is unavailable. Because if you add something to list, ui is need to be recomposed, and it doesn't support animation yet. To solve this problem, i created custom animation with Modifier.graphicsLayer. Code:

val laps = stopWatchViewModel.getLapsStates().collectAsState(initial = emptyList())
LazyColumn(
    modifier = Modifier
        .fillMaxSize()
        .padding(start = 52.dp, end = 52.dp)
) {
    items(items = laps.value) {lap ->
        var lapVisible by remember { mutableStateOf(false) }
        val animatedLapAlpha by animateFloatAsState(
            targetValue = if (lapVisible) 1f else 0f,
            label = "Lap alpha",
            animationSpec = tween(
                durationMillis = 250,
                easing = LinearEasing,
            )
        )
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 16.dp, bottom = 16.dp)
                .graphicsLayer {
                    lapVisible = true
                    alpha = animatedLapAlpha
                },
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(text = lap.lap, color = Color(0xff383838), fontSize = 20.sp)
            Text(text = lap.lapTime, color = Color(0xff808080), fontSize = 20.sp)
            Text(text = lap.totalTime, color = Color(0xfff7f7f7), fontSize = 20.sp)
        }
    }
}

P.s. Later such animations will be available with animateItemPlacement(), but not now