2

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 ?

TNB
  • 49
  • 9

1 Answers1

5

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
}
Thracian
  • 43,021
  • 16
  • 133
  • 222