detectDragGestures

Function

Common
suspend fun PointerInputScope.detectDragGestures(
    onDragStart: (Offset) -> Unit = {},
    onDragEnd: () -> Unit = {},
    onDragCancel: () -> Unit = {},
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit,
) =
    detectDragGestures(
        onDragStart = { _, slopTriggerChange, _ -> onDragStart(slopTriggerChange.position) },
        onDragEnd = { onDragEnd.invoke() },
        onDragCancel = onDragCancel,
        shouldAwaitTouchSlop = { true },
        orientationLock = null,
        onDrag = onDrag,
    )

Gesture detector that waits for pointer down and touch slop in any direction and then calls onDrag for each drag event. It follows the touch slop detection of awaitTouchSlopOrCancellation but will consume the position change automatically once the touch slop has been crossed. @see detectDragGestures with orientation lock for a fuller set of capabilities.

onDragStart called when the touch slop has been passed and includes an Offset representing the last known pointer position relative to the containing element. The Offset can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the ViewConfiguration.minimumTouchTargetSize.

onDragEnd is called after all pointers are up and onDragCancel is called if another gesture has consumed pointer input, canceling this gesture.

Example Usage:

Common
suspend fun PointerInputScope.detectDragGestures(
    orientationLock: Orientation?,
    onDragStart:
        (
            down: PointerInputChange, slopTriggerChange: PointerInputChange, overSlopOffset: Offset,
        ) -> Unit =
        { _, _, _ ->
        },
    onDragEnd: (change: PointerInputChange) -> Unit = {},
    onDragCancel: () -> Unit = {},
    shouldAwaitTouchSlop: () -> Boolean = { true },
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit,
)

A Gesture detector that waits for pointer down and touch slop in the direction specified by orientationLock and then calls onDrag for each drag event. It follows the touch slop detection of awaitTouchSlopOrCancellation but will consume the position change automatically once the touch slop has been crossed, the amount of drag over the touch slop is reported as the first drag event onDrag after the slop is crossed. If shouldAwaitTouchSlop returns true the touch slop recognition phase will be ignored and the drag gesture will be recognized immediately.The first onDrag in this case will report an Offset.Zero.

onDragStart is called when the touch slop has been passed and includes an Offset representing the last known pointer position relative to the containing element as well as the initial down event that triggered this gesture detection cycle. The Offset can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the ViewConfiguration.minimumTouchTargetSize.

onDragEnd is called after all pointers are up with the event change of the up event and onDragCancel is called if another gesture has consumed pointer input, canceling this gesture.

Example Usage:

Parameters

orientationLockOptionally locks detection to this orientation, this means, when this is provided, touch slop detection and drag event detection will be conditioned to the given orientation axis. onDrag will still dispatch events on with information in both axis, but if orientation lock is provided, only events that happen on the given orientation will be considered. This also means that if no event in the orientation is detected we will not dispatch onDrag calls. If no value is provided (i.e. null) touch slop and drag detection will happen on an "any" orientation basis, that is, touch slop will be detected if crossed in either direction and drag events will be dispatched if present in either direction.
onDragStartA lambda to be called when the drag gesture starts, it contains information about the last known PointerInputChange relative to the containing element and the post slop delta, slopTriggerChange. It also contains information about the down event where this gesture started and the overSlopOffset.
onDragEndA lambda to be called when the gesture ends. It contains information about the up PointerInputChange that finished the gesture.
onDragCancelA lambda to be called when the gesture is cancelled either by an error or when it was consumed.
shouldAwaitTouchSlopIndicates if touch slop detection should be skipped.
onDragA lambda to be called for each delta event in the gesture. It contains information about the PointerInputChange and the movement offset.

Code Examples

DetectDragGesturesSample

@Composable
fun DetectDragGesturesSample() {
    val offsetX = remember { mutableStateOf(0f) }
    val offsetY = remember { mutableStateOf(0f) }
    var size by remember { mutableStateOf(Size.Zero) }
    Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
        Box(
            Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
                .size(50.dp)
                .background(Color.Blue)
                .pointerInput(Unit) {
                    detectDragGestures { _, dragAmount ->
                        val original = Offset(offsetX.value, offsetY.value)
                        val summed = original + dragAmount
                        val newValue =
                            Offset(
                                x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                            )
                        offsetX.value = newValue.x
                        offsetY.value = newValue.y
                    }
                }
        )
    }
}