在 Jetpack Compose 中重置可拖动项目的偏移动画

Reset offset animation on draggable item in Jetpack Compose

我有一个可以垂直拖动的绿色方块。但是每当我停止拖动它时,我希望它通过动画将偏移量重置为开始。我这样试过,但我想不通。有人知道怎么做吗?

@Composable
fun DraggableSquare() {
    var currentOffset by remember { mutableStateOf(0F) }
    val resetAnimation by animateIntOffsetAsState(targetValue = IntOffset(0, currentOffset.roundToInt()))

    var shouldReset = false

    Box(contentAlignment = Alignment.TopCenter, modifier = Modifier.fillMaxSize()) {
        Surface(
            color = Color(0xFF34AB52),
            modifier = Modifier
                .size(100.dp)
                .offset {
                    when {
                        shouldReset -> resetAnimation
                        else -> IntOffset(0, currentOffset.roundToInt())
                    }
                }
                .draggable(
                    state = rememberDraggableState { delta -> currentOffset += delta },
                    orientation = Orientation.Vertical,
                    onDragStopped = {
                        shouldReset = true
                        currentOffset = 0F
                    }
                )
        ) {}
    }
}

您可以将偏移量定义为 Animatable
拖动时使用 snapTo 方法将当前值更新为初始值,并使用 onDragStopped 方法启动动画。

val coroutineScope = rememberCoroutineScope()
val offsetY  =  remember { Animatable(0f) }

Box(contentAlignment = Alignment.TopCenter, modifier = Modifier.fillMaxSize()) {
    Surface(
        color = Color(0xFF34AB52),
        modifier = Modifier
            .size(100.dp)
            .offset {
                IntOffset(0, offsetY.value.roundToInt())
            }
            .draggable(
                state = rememberDraggableState { delta ->
                    coroutineScope.launch {
                        offsetY.snapTo(offsetY.value + delta)
                    }
                },
                orientation = Orientation.Vertical,
                onDragStopped = {
                    coroutineScope.launch {
                        offsetY.animateTo(
                            targetValue = 0f,
                            animationSpec = tween(
                                durationMillis = 3000,
                                delayMillis = 0
                            )
                        )
                    }
                }
            )
    ) {
    }
}