在 Jetpack Compose 上检测滑动方向

Detect swipe direction on Jetpack Compose

我正在尝试检测 Compose 中的滑动方向。我为此使用了可拖动修饰符。但是 draggable 只允许检测一个方向(垂直或水平)。我想检测所有方向(左、右、上、下)的滑动。谁能帮我我该怎么做?谢谢!

Modifier.dragGestureFilter detects dragging in any direction. Pass an instance of DragObserver and override onDrag. Here you can detect the swipe direction based on the Offset。此对象具有 xy 值,根据方向为正或负。

您的代码可能如下所示:

Box(
  Modifier.dragGestureFilter(
    dragObserver = object : DragObserver() {
      override fun onDrag(dragDistance: Offset): Offset {
        val (x, y) = dragDistance
        when {
          x > 0 -> { /* right */ }
          x < 0 -> { /* left */ }
        }
        when {
          y > 0 -> { /* down */ }
          y < 0 -> { /* up */ }
        }
      }
    }
  )
)

要实际移动对象,您必须应用 Modifier.offset 以及在 onDrag 中更新的值。

有了 1.0.0 你可以使用 pointerInput modifier controlling the dragging gesture with the detectDragGestures 函数。

类似于:

Box(modifier = Modifier.fillMaxSize()) {
    var offsetX by remember { mutableStateOf(0f) }
    var offsetY by remember { mutableStateOf(0f) }

    Box(
        Modifier
            .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
            .size(100.dp, 100.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    change.consumeAllChanges()

                    val (x,y) = dragAmount
                    when {
                        x > 0 ->{ /* right */ }
                        x < 0 ->{ /* left */ }
                    }
                    when {
                        y > 0 -> { /* down */ }
                        y < 0 -> { /* up */ }
                    }

                    offsetX += dragAmount.x
                    offsetY += dragAmount.y
                }
            }
    )
}

这是一个更修改的方式来获得方向,水平滑动和垂直滑动不冲突,并确保return用户结束滑动后的方向。

var direction by remember { mutableStateOf(-1)}

Box(
    modifier = Modifier
        .pointerInput(Unit) {
            detectDragGestures(
                onDrag = { change, dragAmount ->
                    change.consumeAllChanges()

                    val (x, y) = dragAmount
                    if(abs(x) > abs(y)){
                        when {
                            x > 0 -> {
                                //right
                                direction = 0
                            }
                            x < 0 -> {
                                // left
                                direction = 1
                            }
                        }
                    }else{
                        when {
                            y > 0 -> {
                                // down
                                direction = 2
                            }
                            y < 0 -> {
                                // up
                                direction = 3
                            }
                        }
                    }

                },
                onDragEnd = {
                    when (direction){
                        0 -> {
                            //right swipe code here }
                        1 -> {
                            // left swipe code here
                        }
                        2 -> {
                            // down swipe code here
                        }
                        3 -> {
                            // up swipe code here
                        }
                    }
                }
            )
        
)