Helper Utility for Jetpack Compose’s Pointer Input Scope

Gesture Association with Jetpack Compose in Android

Nirbhay Pherwani
Droid Digest
2 min readJul 16, 2023

--

Image sourced from an article published on Justinmind

Jetpack Compose provides a powerful modifier called pointerInputScope, which allows us to detect various gestures such as dragging, long-press, and tapping performed by the user on the screen. Often, we want to perform certain operations once a specific gesture, like dragging in a particular direction, is completed.

To streamline this process, we can create a helper function that consolidates all the gesture-related options into one file. This function can then be invoked with the necessary actions to be performed when the gestures are complete, for example make a button appear when user drags towards the left direction.

The following block of code listens for drag gestures using detectDragGestures but we can extend the same block to listen for other gestures that pointerInputScope supports.

Code

enum class GestureDirections {
DOWN,
UP,
LEFT,
RIGHT,
UNKNOWN
}

object GestureAssociation {
suspend fun associateGesture(
pointerInputScope: PointerInputScope,
ifDirectionIsDown: (() -> Unit)? = null,
ifDirectionIsUp: (() -> Unit)? = null,
ifDirectionIsLeft: (() -> Unit)? = null,
ifDirectionIsRight: (() -> Unit)? = null
) {
var gestureDirection = GestureDirections.UNKNOWN

pointerInputScope.apply {
detectDragGestures(
onDrag = { change, dragAmount ->
change.consume()
val (x, y) = dragAmount
gestureDirection = if (StrictMath.abs(x) <= StrictMath.abs(y)) {
if (y > 0)
GestureDirections.DOWN
else
GestureDirections.UP
} else {
if (x > 0)
GestureDirections.RIGHT
else
GestureDirections.LEFT
}
},
onDragEnd = {
when (gestureDirection) {
GestureDirections.DOWN -> {
ifDirectionIsDown?.invoke()
}
GestureDirections.UP -> {
ifDirectionIsUp?.invoke()
}
GestureDirections.RIGHT -> {
ifDirectionIsRight?.invoke()
}
GestureDirections.LEFT -> {
ifDirectionIsLeft?.invoke()
}
else -> {}
}
}
)
}
}
}

Usage

Box(
modifier = Modifier
.background(Color.LightGray)
.fillMaxSize()
.pointerInput(Unit) {
GestureAssociation.associateGesture(
this,
ifDirectionIsDown = { showButton() })
},
){}

In this example when the user will drag on the screen towards the downwards direction the block of code inside isDirectionIsDown will get executed.

By encapsulating gesture handling logic within a helper function like associateGesture, we can easily handle drag gestures in Jetpack Compose. This approach promotes code reusability and simplifies the implementation of other gesture-based interactions throughout the app.

Additionally, it frees us from the complexities of calculating precise user actions, allowing us to focus on creating delightful user experiences. Feel free to customize and extend this approach to support other gestures provided by pointerInputScope.

Have fun coding!

--

--