user16885569
user16885569

Reputation: 311

Jetpack Compose: how to disable gesture detection on children

Is there a built-in Modifier that disables any gesture detection / pointer input interaction of its children?

e.g.

@Composable
fun Foo() {
    Box(modifier = Modifier.gesturesEnabled(enabled = false)) {
        BasicText(text = "Hello", modifier = Modifier.clickable { // clickable is not enabled
            // ...
        })
    }
}

I could roll my own (very simple) implementation using a CompositionLocal:

val LocalGesturesEnabled = compositionLocalOf { mutableStateOf(true) }

fun Modifier.myClickable(onClick: () -> Unit, enabled: Boolean = true) = composed {
    clickable(enabled = enabled && LocalGesturesEnabled.current.value, onClick)
}

But it won't work with third party composables or with more complex composables like LazyList.

Upvotes: 24

Views: 12480

Answers (1)

Phil Dukhov
Phil Dukhov

Reputation: 87864

I believe the reason for the lack of such a system modifier is that you have to show the user that gestures are disabled by using different states for enabled/disabled controls, or by using a semi-transparent overlay view, etc.

But technically using pointerInput modifier you can get all touch events with awaitPointerEvent.

With the pass = PointerEventPass.Initial parameter you will receive events before all child views, and then you can mark the event as handled with consumeAllChanges, so that children will no longer receive them.

fun Modifier.gesturesDisabled(disabled: Boolean = true) =
    if (disabled) {
        pointerInput(Unit) {
            awaitPointerEventScope {
                // we should wait for all new pointer events
                while (true) {
                    awaitPointerEvent(pass = PointerEventPass.Initial)
                        .changes
                        .forEach(PointerInputChange::consume)
                }
            }
        }
    } else {
        this
    }

If you wanna learn more about custom gesture processing, check out this article

Upvotes: 46

Related Questions