将 SwipeToDismiss LazyColumn 项目恢复到原始状态?

Rah*_*hul 7 android kotlin android-jetpack-compose

我可以做到SwipeToDismiss,但我想将刷卡的LazyColumn项目恢复到原始状态。我不想删除滑动的项目,但想将其恢复到原始状态。

RecyclerView我只需调用即可轻松实现此目的notifyItemChanged(),但不知道如何在LazyColumn.

下面是我的代码:

val dataList = remember{ mutableStateListOf<ListItem>()}
for(i in 0..100){
    dataList.add(ListItem("$i", "'$i' is the item number."))
}

LazyColumn(Modifier.fillMaxSize()){
    items(dataList, key = {it.id}){ item ->
        val dismissState = rememberDismissState(
            confirmStateChange = {
                if(it == DismissedToEnd || it == DismissedToStart){
                    Handler(Looper.getMainLooper()).postDelayed({
                        //dataList.remove(item)
                    }, 1000)
                }
                true
            }
        ) 
        SwipeToDismiss(
            state = dismissState,
            directions = setOf(StartToEnd, EndToStart),
            dismissThresholds = { direction ->
                FractionalThreshold(if (direction == StartToEnd || direction == EndToStart) 0.25f else 0.5f)
            },
            background = {
                val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
                val color by animateColorAsState(
                    targetValue = when(dismissState.targetValue){
                        Default -> Color.LightGray
                        DismissedToEnd -> Color.Green
                        DismissedToStart -> Color.Red
                    }
                )
                val icon = when(direction){
                    StartToEnd -> Icons.Default.Done
                    EndToStart -> Icons.Default.Delete
                }
                val scale by animateFloatAsState(
                    if (dismissState.targetValue == Default) 0.8f else 1.2f
                )
                val alignment = when (direction) {
                    StartToEnd -> Alignment.CenterStart
                    EndToStart -> Alignment.CenterEnd
                }
                Box(modifier = Modifier
                    .fillMaxSize()
                    .background(color)
                    .padding(start = 12.dp, end = 12.dp),
                    contentAlignment = alignment
                ){
                    Icon(icon, contentDescription = "Icon", modifier = Modifier.scale(scale))
                }
            },
            dismissContent = {ItemScreen(dismissState = dismissState, item = item)}
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 9

您可以等待currentValue变为非状态Default并重置状态:

根据Thinking in Compose,可组合函数应该没有副作用 - 您不应该直接重置可组合范围中的状态。对于这种情况,您需要使用一种特殊的副作用函数,更多信息可以在副作用文档中找到。

重组可能会发生多次,动画期间最多一帧一次,并且不使用副作用函数将导致多次调用,这可能会导致动画问题。

作为DismissState.reset()一个suspend函数,LaunchedEffect非常适合这里:它已经在协程作用域上运行。

if (dismissState.currentValue != DismissValue.Default) {
    LaunchedEffect(Unit) {
        dismissState.reset()
    }
}
Run Code Online (Sandbox Code Playgroud)