---
title: "detectTapGestures"
description: "Detects tap, double-tap, and long press gestures and calls [onTap], [onDoubleTap], and
[onLongPress], respectively, when detected. [onPress] is called when the press is detected and
the [PressGestureScope.tryAwaitRelease] and [PressGestureScope.awaitRelease] can be used to
detect when pointers have released or the gesture was canceled. The first pointer down and final
pointer up are consumed, and in the case of long press, all changes after the long press is
detected are consumed.

Each function parameter receives an [Offset] representing the 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].

When [onDoubleTap] is provided, the tap gesture is detected only after the
[ViewConfiguration.doubleTapMinTimeMillis] has passed and [onDoubleTap] is called if the second
tap is started before [ViewConfiguration.doubleTapTimeoutMillis]. If [onDoubleTap] is not
provided, then [onTap] is called when the pointer up has been received.

After the initial [onPress], if the pointer moves out of the input area, the position change is
consumed, or another gesture consumes the down or up events, the gestures are considered
canceled. That means [onDoubleTap], [onLongPress], and [onTap] will not be called after a gesture
has been canceled.

If the first down event is consumed somewhere else, the entire gesture will be skipped, including
[onPress]."
type: "function"
---

<div class='type'>Function</div>


<a id='references'></a>
<div class='sourceset sourceset-common'>Common</div>


```kotlin
suspend fun PointerInputScope.detectTapGestures(
    onDoubleTap: ((Offset) -> Unit)? = null,
    onLongPress: ((Offset) -> Unit)? = null,
    onPress: suspend PressGestureScope.(Offset) -> Unit = NoPressGesture,
    onTap: ((Offset) -> Unit)? = null,
) = coroutineScope {
    val pressScope = PressGestureScopeImpl(this@detectTapGestures)

    awaitEachGesture {
        processTapGesture(
            scope = this@coroutineScope,
            pressScope = pressScope,
            onDoubleTap = onDoubleTap,
            onLongPress = onLongPress,
            onPress = onPress,
            onTap = onTap,
        )
    }
}
```


Detects tap, double-tap, and long press gestures and calls `onTap`, `onDoubleTap`, and
`onLongPress`, respectively, when detected. `onPress` is called when the press is detected and
the `PressGestureScope.tryAwaitRelease` and `PressGestureScope.awaitRelease` can be used to
detect when pointers have released or the gesture was canceled. The first pointer down and final
pointer up are consumed, and in the case of long press, all changes after the long press is
detected are consumed.

Each function parameter receives an `Offset` representing the 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`.

When `onDoubleTap` is provided, the tap gesture is detected only after the
`ViewConfiguration.doubleTapMinTimeMillis` has passed and `onDoubleTap` is called if the second
tap is started before `ViewConfiguration.doubleTapTimeoutMillis`. If `onDoubleTap` is not
provided, then `onTap` is called when the pointer up has been received.

After the initial `onPress`, if the pointer moves out of the input area, the position change is
consumed, or another gesture consumes the down or up events, the gestures are considered
canceled. That means `onDoubleTap`, `onLongPress`, and `onTap` will not be called after a gesture
has been canceled.

If the first down event is consumed somewhere else, the entire gesture will be skipped, including
`onPress`.



