如何在 Android Jetpack Compose 中创建任意方向的拖动手势
How to create a drag gesture in any direction in Android Jetpack Compose
我想在 @Composable 中检测手势,这将允许我在屏幕上向任何方向拖动元素。
我尝试使用 LongPressDragObserver,但在拖动了一会儿之后,它捕捉到一个单一的 Orientation(Horizontally 或 Vertically) 和 Offset 对于另一个 Orientation 根本没有改变(一直等于0)
我想要实现的示例功能:
长按 FAB 并在屏幕上拖动它,使其位置始终在用户的手指下方。
我正在使用 Compose 1.0.0-alpha04
仅向一个方向拖动的示例代码(感谢 Rafsanjani)
.dragGestureFilter(dragObserver = object : DragObserver {
override fun onDrag(dragDistance: Offset): Offset {
val newX = dragDistance.x + verticalOffset.value
val newY = dragDistance.y + horizontalOffset.value
verticalOffset.value = newX
horizontalOffset.value = newY
return dragDistance
}
})
您可以将 Modifier.pointerInput
与 detectDragGestures
结合使用,以达到您想要的效果。
示例:
@Composable
fun Drag2DGestures() {
var size by remember { mutableStateOf(400.dp) }
val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
Box(modifier = Modifier.size(size)){
Box(
Modifier
.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
.background(Color.Blue)
.size(50.dp)
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
change.consumeAllChanges()
offsetX.value = (offsetX.value + dragAmount.x)
.coerceIn(0f, size.width.toFloat() - 50.dp.toPx())
offsetY.value = (offsetY.value + dragAmount.y)
.coerceIn(0f, size.height.toFloat() - 50.dp.toPx())
}
}
)
Text("Drag the box around", Modifier.align(Alignment.Center))
}
}
会产生这个结果:
ٍٍٍ抱歉 jank/drop 帧数,内置模拟器录制器无法流畅录制 60fps
撰写版本:alpha-11
我想在 @Composable 中检测手势,这将允许我在屏幕上向任何方向拖动元素。
我尝试使用 LongPressDragObserver,但在拖动了一会儿之后,它捕捉到一个单一的 Orientation(Horizontally 或 Vertically) 和 Offset 对于另一个 Orientation 根本没有改变(一直等于0)
我想要实现的示例功能:
长按 FAB 并在屏幕上拖动它,使其位置始终在用户的手指下方。
我正在使用 Compose 1.0.0-alpha04
仅向一个方向拖动的示例代码(感谢 Rafsanjani)
.dragGestureFilter(dragObserver = object : DragObserver {
override fun onDrag(dragDistance: Offset): Offset {
val newX = dragDistance.x + verticalOffset.value
val newY = dragDistance.y + horizontalOffset.value
verticalOffset.value = newX
horizontalOffset.value = newY
return dragDistance
}
})
您可以将 Modifier.pointerInput
与 detectDragGestures
结合使用,以达到您想要的效果。
示例:
@Composable
fun Drag2DGestures() {
var size by remember { mutableStateOf(400.dp) }
val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
Box(modifier = Modifier.size(size)){
Box(
Modifier
.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
.background(Color.Blue)
.size(50.dp)
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
change.consumeAllChanges()
offsetX.value = (offsetX.value + dragAmount.x)
.coerceIn(0f, size.width.toFloat() - 50.dp.toPx())
offsetY.value = (offsetY.value + dragAmount.y)
.coerceIn(0f, size.height.toFloat() - 50.dp.toPx())
}
}
)
Text("Drag the box around", Modifier.align(Alignment.Center))
}
}
会产生这个结果:
ٍٍٍ抱歉 jank/drop 帧数,内置模拟器录制器无法流畅录制 60fps
撰写版本:alpha-11