Reputation: 311
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
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