You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中AnimatedVisibility淡入动画对重组项失效问题

需求与问题

我需要基于用户选择对LazyColumn内部FlowRow中的项进行筛选,并添加动画效果。为避免滚动位置跳动,要求项不被移出组合,但之前筛选中已存在于组合内的项不会触发AnimatedVisibility的fadeIn动画,收缩、展开、滑动等其他动画需正常工作。

从演示动图可见:首次筛选时item1、第二次筛选时item3均未执行淡入动画。
演示动图

ViewModel及筛选逻辑(部分代码省略)

class SomeViewModel : ViewModel() {

    private val list = listOf(
        SomeData(id = "1", value = "Row1"),
        SomeData(id = "2", value = "Row2"),
        SomeData(id = "3", value = "Row3"),
        SomeData(id = "4", value = "Row4"),
        SomeData(id = "5", value = "Row5")
    )

    var itemList by mutableStateOf(list)

    var filter: Int = 0

    fun filter() {
        if (filter % 3 == 0) {
            itemList = listOf(
                list[0],
                list[1],
                list[2]
            )
        } else if (filter % 3 == 1) {
            itemList = listOf(
                list[1],
                list[2]
            )
        } else {
            itemList = listOf(
                list[0],
                list[2],
                list[3]
            )
        }

        filter++
    }
}

data class SomeData(val id: String, val value: String)

包含动画逻辑的Composable

@Composable
private fun StaggeredList(
    filter: String,
    itemList: List<SomeData>,
) {
    BoxWithConstraints(
        modifier = Modifier
    ) {

        val itemWidth = (maxWidth - 8.dp) / 2

        FlowRow(
            modifier = Modifier,
            maxItemsInEachRow = 2,
            horizontalArrangement = Arrangement.spacedBy(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            itemList.forEachIndexed { index, it ->
                key(it.id) {

                    var visible by remember {
                        mutableStateOf(false)
                    }

                    LaunchedEffect(filter) {
                        visible = false
                        delay(2000)
                        visible = true
                    }

                    AnimatedVisibility(
                        visible = visible,
                        enter = fadeIn(tween(2000)),
                        exit = fadeOut(tween(2000))
                    ) {
                        MyRow(
                            modifier = Modifier.size(itemWidth, 200.dp),
                            item = it
                        )
                    }
                }
            }
        }
    }
}

(注:原代码中itemList.forEachIndexed { index, it -为笔误,已修正为->)

其余复现代码

@Preview
@Composable
private fun FlowRowCompositionPreview() {
    val viewModel = viewModel<SomeViewModel>()
    MyComposable(viewModel)
}

@Composable
fun MyComposable(someViewModel: SomeViewModel) {

    Column(modifier = Modifier.fillMaxSize().background(backgroundColor)) {

        val itemList = someViewModel.itemList

        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.spacedBy(8.dp),
            contentPadding = PaddingValues(16.dp)
        ) {

            items(5) {
                Box(
                    modifier = Modifier
                        .background(Color.Red, RoundedCornerShape(16.dp))
                        .fillMaxWidth().height(100.dp)
                )
            }

            item {
                Button(
                    modifier = Modifier.padding(16.dp).fillMaxWidth(),
                    onClick = {
                        someViewModel.filter()
                    }
                ) {
                    Text("Filter")
                }
            }
            item {
                StaggeredList(
                    filter = someViewModel.filter.toString(),
                    itemList = itemList
                )
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Thracian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:28:13