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

Jetpack Compose中列表项删除时的淡出动画实现咨询

给FlowColumn/FlowRow列表项添加删除淡出动画

直接从mutableStateList中移除项会立刻触发重组,导致列表项直接消失,没法展示动画。要实现删除前的淡出效果,得先让目标项完成动画,再真正从数据源中移除,核心思路是给每个项增加「待删除」状态,通过动画回调触发最终的数据删除。

实现步骤

  1. 定义带删除状态的数据类
    给列表项增加isDeleting标记用来控制动画触发,同时用唯一id定位项(避免FlowColumn换行后索引混乱的问题):

    data class ListItem(
        val id: String,
        val text: String,
        var isDeleting: Boolean = false
    )
    
  2. 父Composable维护状态与删除逻辑
    不再直接删除列表项,而是先标记该项为待删除,等待动画结束后再移除:

    @Composable
    fun ParentComposable() {
        val listItems = remember {
            mutableStateListOf(
                ListItem(id = "1", text = "第一项"),
                ListItem(id = "2", text = "第二项"),
                ListItem(id = "3", text = "第三项")
            )
        }
    
        // 处理删除请求:先标记待删除,动画结束后移除
        val onDeleteClick = { targetId: String ->
            listItems.find { it.id == targetId }?.let { item ->
                item.isDeleting = true
            }
        }
    
        FlowColumn(modifier = Modifier.padding(16.dp)) {
            listItems.forEach { item ->
                ListItemComposable(
                    item = item,
                    onDeleteClick = { onDeleteClick(item.id) },
                    onAnimationEnd = {
                        listItems.remove(item)
                    }
                )
            }
        }
    }
    
  3. 子Composable实现淡出动画
    用AnimatedVisibility包裹列表项,设置淡出退出动画,在动画完成回调中通知父Composable移除数据:

    @Composable
    fun ListItemComposable(
        item: ListItem,
        onDeleteClick: () -> Unit,
        onAnimationEnd: () -> Unit
    ) {
        AnimatedVisibility(
            visible = !item.isDeleting,
            exit = fadeOut(animationSpec = tween(500)),
            onExitCompleted = { onAnimationEnd() }
        ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 8.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(text = item.text, modifier = Modifier.weight(1f))
                IconButton(onClick = onDeleteClick) {
                    Icon(Icons.Default.Delete, contentDescription = "删除")
                }
            }
        }
    }
    

关键说明

  • 用AnimatedVisibility的onExitCompleted回调确保动画完全结束后再删除数据,避免动画中途项被移除导致的异常。
  • 采用id而非索引定位列表项,适配FlowColumn/FlowRow的流式布局特性,防止布局换行后索引失效的问题。
  • 动画时长可以通过tween参数调整,比如把500改成你需要的毫秒值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:20:03