本文介绍了AnimatedVisibility&;SwipeToDismisse输入动画不会触发-Jetpack Compose的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
好的,我一直在尝试在我的应用程序中实现滑动删除功能。每当我滑动列表中的一项时,我都能看到后面的红色背景,一切都运行得很好。同时,当我删除一个项目时,滑动动画也被成功触发。(尽管我不确定使用延迟是不是一个好主意?我想不出任何其他方法来做这件事)。但是向数据库/列表添加项目时输入动画不起作用,我不确定原因。以下是我的Lazy专栏的代码
@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)
if (isDismissed && dismissDirection == DismissDirection.EndToStart
) {
val scope = rememberCoroutineScope()
scope.launch {
delay(300)
onSwipeToDelete(Action.DELETE, task)
}
}
AnimatedVisibility(
visible = !isDismissed,
exit = shrinkVertically(
animationSpec = tween(
durationMillis = 300,
)
),
enter = expandVertically(
animationSpec = tween(
durationMillis = 300
)
)
) {
SwipeToDismiss(
state = dismissState,
directions = setOf(DismissDirection.EndToStart),
dismissThresholds = { FractionalThreshold(0.2f) },
background = { RedBackground() },
dismissContent = {
LazyColumnItem(
toDoTask = task,
navigateToTaskScreen = navigateToTaskScreen
)
}
)
}
}
}
}
推荐答案
首先,您不应该在Composable内执行任何状态更改操作。取而代之的是使用一种副作用,通常是LaunchedEffect(key) { }
:块的内容将在第一次渲染时被调用,并且每次关键点与最后一次渲染不同。此外,在内部,您已经在一个协程作用域,所以没有必要启动它。有关副作用的更多信息,请参阅documentation。
列表中的项目动画为not yet supported。只需向项目中添加AnimatedVisibility
即可。
当Compose第一次在撰写树中看到AnimatedVisibility
时,它在没有动画的情况下绘制(或不绘制)它。
当下一次重新合成visible
不同于上次渲染时间时,它会生成动画。
因此,要使其按您希望的方式工作,您可以执行以下操作:
- 添加
itemAppeared
状态值,列表中的项目最初会被隐藏,渲染后使用副作用使其立即可见 - 添加
columnAppeared
将阻止初始外观动画-如果没有它,在屏幕渲染时,所有项目都将显示得太生动
@Composable
fun DisplayTasks(
tasks: List<ToDoTask>,
onSwipeToDelete: (Action, ToDoTask) -> Unit,
) {
var columnAppeared by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
columnAppeared = true
}
LazyColumn {
items(
items = tasks,
key = { task ->
task.id
}
) { task ->
val dismissState = rememberDismissState()
val dismissDirection = dismissState.dismissDirection
val isDismissed = dismissState.isDismissed(DismissDirection.EndToStart)
if (isDismissed && dismissDirection == DismissDirection.EndToStart
) {
LaunchedEffect(Unit) {
delay(300)
onSwipeToDelete(Action.DELETE, task)
}
}
var itemAppeared by remember { mutableStateOf(!columnAppeared) }
LaunchedEffect(Unit) {
itemAppeared = true
}
AnimatedVisibility(
visible = itemAppeared && !isDismissed,
exit = shrinkVertically(
animationSpec = tween(
durationMillis = 300,
)
),
enter = expandVertically(
animationSpec = tween(
durationMillis = 300
)
)
) {
SwipeToDismiss(
state = dismissState,
directions = setOf(DismissDirection.EndToStart),
dismissThresholds = { FractionalThreshold(0.2f) },
background = {
Box(
Modifier
.background(Color.Red)
.fillMaxSize()
)
},
dismissContent = {
Text(task.id)
}
)
}
}
}
}
这篇关于AnimatedVisibility&;SwipeToDismisse输入动画不会触发-Jetpack Compose的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!