首页 > 解决方案 > 如何在 Android Jetpack Compose 中创建任意方向的拖动手势

问题描述

我想在@Composable中检测一个手势,这将允许我在屏幕上向任何方向拖动一个元素。

我尝试使用LongPressDragObserver但是在拖动了一点之后,它会捕捉到一个方向水平垂直)并且偏移量根本不会改变另一个方向(它将一直等于 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 
  } 
})

标签: androidandroid-jetpack-compose

解决方案


你可以使用Modifier.pointerInputwithdetectDragGestures来做你想做的事情。

例子:

   @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))
    }
}

将产生这个结果:

ٍٍٍ 很抱歉出现卡顿/丢帧,内置模拟器录制器无法流畅录制 60fps

在此处输入图像描述

撰写版本:alpha-11


推荐阅读