How can i use multiple gesture in the same Android Compose View? [duplicate]
Asked Answered
S

1

5

I would like to use drag and tap gestures in the same view.

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

                                detectDragGestures { change, dragAmount ->
                                    change.consumeAllChanges()
                                    dragAmountX = dragAmount.x
                                    dragAmountY = dragAmount.y
                                }
                            }
                    )

I tried this way but only tap gesture is working. How can i use tap and drag gesture at the same time in a view ?

Salzburg answered 13/7, 2022 at 20:39 Comment(0)
C
9

You need to chain them as in answer here.

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

  } 

And change.consumeAllChanges() is deprecated as of 1.2.0-beta01 it's change.consume(). What consume() does is it prevents continuous gestures like drag, transform or scroll to receiving events because all the gestures above check change.isConsumed true before looping event.

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")

            }
        )
    }

Let me add as side note as answer in the link. detectGestures call change.consume() just after it invokes onDrag() callback. Because of that unless you do some conditional event check inside onDrag() calling consume.change() is useless. When a PointerInputChange is consumed PointerInputChange.positionChange() returns Offset.Zero and PointerInputChange.isConsumed true.

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
}
Charleton answered 13/7, 2022 at 20:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.