Jetpack Compose Gestures
Counterpart of onTouchEvent
for Jetpack Compose and transform gesture with specific number of pointers
gestures.mp4
Modifier.pointerMotionEvents
Creates a modifier for processing pointer motion input within the region of the modified element.
After AwaitPointerEventScope.awaitFirstDown
returns a PointerInputChange
followed by onDown
at first pointer contact. Moving any pointer invokes AwaitPointerEventScope.awaitPointerEvent
then onMove
is called. When last pointer is up onUp
is called.
To prevent other pointer functions that call awaitFirstDown
or awaitPointerEvent
(scroll, swipe, detect functions) call PointerInputChange.consume()
in onDown
, and call PointerInputChange.consume()
in onMove
block.
fun Modifier.pointerMotionEvents(
vararg keys: Any?,
onDown: (PointerInputChange) -> Unit = {},
onMove: (PointerInputChange) -> Unit = {},
onUp: (PointerInputChange) -> Unit = {},
delayAfterDownInMillis: Long = 0L
) = this.then(
Modifier.pointerInput(keys) {
detectMotionEvents(onDown, onMove, onUp, delayAfterDownInMillis)
}
)
pointerMotionEventList returns list of pointers in onMove
fun Modifier.pointerMotionEventList(
key1: Any? = Unit,
onDown: (PointerInputChange) -> Unit = {},
onMove: (List<PointerInputChange>) -> Unit = {},
onUp: (PointerInputChange) -> Unit = {},
delayAfterDownInMillis: Long = 0L
)
delayAfterDownInMillis
parameter invokes Coroutines delay betweenonDown
, andonMove
. There is a delay about 20ms between in View'sonTouchEvent
first touch and move, similar delay might be required with Compose too, especially when drawing toCanvas
which misses very fast events, Delaying move behavior might be required to detect whether is touch is in required region of Composable at first pointer contact.
PointerInputChange
down and move events should be consumed if you need to prevent other gestures like scroll or other pointerInputs to not intercept your gesture
Modifier.pointerMotionEvents(
onDown = {
// When down is consumed
it.consume()
},
onMove = {
// Consuming move prevents scroll other events to not get this move event
it.consume()
},
delayAfterDownInMillis = 20
)
You can refer this answer for details.
Modifier.detectTransformGesturesAndChanges
A gesture detector for rotation, panning, and zoom. Once touch slop has been reached, the user can use rotation, panning and zoom gestures. onGesture
will be called when any of the rotation, zoom or pan occurs, passing the rotation angle in degrees, zoom in scale factor and pan as an offset in pixels. Each of these changes is a difference between the previous call and the current gesture. This will consume all position changes after touch slop has been reached. onGesture will also provide centroid of all the pointers that are down.
After gesture started when last pointer is up onGestureEnd
is triggered. pointerList
returns info about pointers that are available to this gesture
Usage
Modifier.pointerInput(Unit) {
detectTransformGesturesAndChanges(
onGesture = { gestureCentroid: Offset,
gesturePan: Offset,
gestureZoom: Float,
gestureRotate: Float,
pointerList: List<PointerInputChange> ->
},
onGestureEnd = {
transformDetailText = "GESTURE END"
}
)
}
Modifier.detectPointerTransformGestures
Transform gesture as detectTransformGestures
except with gestureEnd
callback, returns number of pointers that are down and checks for requisite and number of pointers before continuing transform gestures. when requisite is not met gesture is on hold and ends when last pointer is up. This might be useful in scenarios like not panning when pointer number is higher than 1, or scenarios require specific conditions to be met
Modifier
.pointerInput(Unit) {
detectPointerTransformGestures(
numberOfPointers = 1,
requisite = PointerRequisite.GreaterThan,
onGesture = { gestureCentroid: Offset,
gesturePan: Offset,
gestureZoom: Float,
gestureRotate: Float,
numberOfPointers: Int ->
},
onGestureEnd = {
transformDetailText = "GESTURE END"
}
)
}
Gesture Tutorial
If you need more detailed tutorial about Jetpack Compose gestures check this tutorial
Gradle Setup
To get a Git project into your build:
- Step 1. Add the JitPack repository to your build file Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
- Step 2. Add the dependency
dependencies {
implementation 'com.github.SmartToolFactory:Compose-Extended-Gestures:Tag'
}