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

Jetpack Compose中AnimatedVisibility搭配SwipeToDismiss新增项入场动画不触发

问题原因
  1. AnimatedVisibility初始状态问题:你当前把AnimatedVisibility的visible参数仅和删除状态isDismissed绑定,新增列表项时,新生成的item的rememberDismissState默认isDismissed为false,所以AnimatedVisibility初始化时visible就是true,直接渲染为可见状态,不会触发enter动画。
  2. 删除逻辑硬编码delay不是最优解:硬编码300ms延迟依赖动画时长硬匹配,后续如果改动画时长还要同步改delay值,容易出问题。
修复方案

1. 新增item入场动画修复

你可以直接使用Compose LazyColumn官方提供的item动画API,不需要在每个item内部套AnimatedVisibility来处理入场,只需要给每个item加animateItemPlacement修饰符,同时保留原有AnimatedVisibility处理删除的退出动画即可,调整后代码如下:

@Composable
fun DisplayTasks(
    tasks: List<ToDoTask>,
    onSwipeToDelete: (Action, ToDoTask) -> Unit,
    navigateToTaskScreen: (Int) -> Unit
) {
    LazyColumn {
        items(
            items = tasks,
            key = { task ->
                task.id
            }
        ) { task ->
            val dismissState = rememberDismissState()
            val dismissDirection = dismissState.dismissDirection
            val isDismissed = dismissState.isDismissed(DismissDirection.EndToStart)
            
            // 用LaunchedEffect替代手动创建协程作用域,性能更稳定
            LaunchedEffect(isDismissed) {
                if (isDismissed && dismissDirection == DismissDirection.EndToStart) {
                    delay(300)
                    onSwipeToDelete(Action.DELETE, task)
                }
            }

            AnimatedVisibility(
                visible = !isDismissed,
                exit = shrinkVertically(
                    animationSpec = tween(
                        durationMillis = 300,
                    )
                ),
                // 新增animateItemPlacement处理新增/排序的入场/位移动画
                modifier = Modifier.animateItemPlacement(
                    animationSpec = tween(durationMillis = 300)
                )
            ) {
                SwipeToDismiss(
                    state = dismissState,
                    directions = setOf(DismissDirection.EndToStart),
                    dismissThresholds = { FractionalThreshold(0.2f) },
                    background = { RedBackground() },
                    dismissContent = {
                        LazyColumnItem(
                            toDoTask = task,
                            navigateToTaskScreen = navigateToTaskScreen
                        )
                    }
                )
            }
        }
    }
}

2. 删除逻辑delay优化(可选)

如果你不想硬编码delay,可以监听AnimatedVisibility的动画结束回调来触发删除操作,调整后不需要再写LaunchedEffect的delay逻辑:

AnimatedVisibility(
    visible = !isDismissed,
    exit = shrinkVertically(tween(300)),
    modifier = Modifier.animateItemPlacement(tween(300)),
    // 退出动画执行完成后自动触发删除逻辑,无需硬编码延迟时长
    onExitFinished = {
        onSwipeToDelete(Action.DELETE, task)
    }
) {
    // 原有SwipeToDismiss内容不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:06:03