如何在同一个 Android Compose 视图中使用多个手势?

TNB*_*TNB 4 android gesture android-jetpack-compose

我想在同一视图中使用拖动和点击手势。

 Canvas(
                        modifier = Modifier
                            .fillMaxSize()
                            .pointerInput(Unit) {
                                detectTapGestures(
                                    onDoubleTap = {
                                        Log.i("Double Tap","Clicked")
                                    }
                                )

                                detectDragGestures { change, dragAmount ->
                                    change.consumeAllChanges()
                                    dragAmountX = dragAmount.x
                                    dragAmountY = dragAmount.y
                                }
                            }
                    )
Run Code Online (Sandbox Code Playgroud)

我尝试了这种方法,但只有点击手势有效。如何在视图中同时使用点击和拖动手势?

Thr*_*ian 8

您需要像此处的答案一样将它们链接起来。

Modifier
  .pointerInput(keys){
    
  } 
  .pointerInput(keys){
   

  } 
Run Code Online (Sandbox Code Playgroud)

change.consumeAllChanges()从 1.2.0-beta01 开始,它已被弃用change.consume()。Consumer() 的作用是防止连续手势(例如拖动、变换或滚动)接收事件,因为上面的所有手势都会change.isConsumed true在循环事件之前进行检查。

val context = LocalContext.current

val modifier = Modifier
    .pointerInput(Unit) {
        detectTapGestures(
            onPress = {
                Toast
                    .makeText(context, "onPress", Toast.LENGTH_SHORT)
                    .show()
            },
            onTap = {
                Toast
                    .makeText(context, "onTap", Toast.LENGTH_SHORT)
                    .show()
            }
        )
    }

    .pointerInput(Unit) {
        detectDragGestures(
            onDragStart = {
                Toast
                    .makeText(context, "onDragStart", Toast.LENGTH_SHORT)
                    .show()
            },
            onDrag = { change, dragAmount ->
                println("DRAGGING $dragAmount")

            }
        )
    }
Run Code Online (Sandbox Code Playgroud)

让我在链接中添加旁注作为答案。在调用回调后立即detectGestures调用。因此,除非您在 调用内部进行一些条件事件检查,否则是没有用的。当 a被消耗时,返回 Offset.Zero 和 PointerInputChange.isConsumed true。change.consume()onDrag()onDrag()consume.change()PointerInputChangePointerInputChange.positionChange()

private fun PointerInputChange.positionChangeInternal(ignoreConsumed: Boolean = false): Offset {
    val previousPosition = previousPosition
    val currentPosition = position

    val offset = currentPosition - previousPosition

    return if (!ignoreConsumed && isConsumed) Offset.Zero else offset
}
Run Code Online (Sandbox Code Playgroud)