Jetpack Compose:如何禁用儿童手势检测
Jetpack Compose: how to disable gesture detection on children
是否有内置 Modifier
禁用其子项的任何手势检测/指针输入交互?
例如
@Composable
fun Foo() {
Box(modifier = Modifier.gesturesEnabled(enabled = false)) {
BasicText(text = "Hello", modifier = Modifier.clickable { // clickable is not enabled
// ...
})
}
}
我可以使用 CompositionLocal
:
推出自己的(非常简单的)实现
val LocalGesturesEnabled = compositionLocalOf { mutableStateOf(true) }
fun Modifier.myClickable(onClick: () -> Unit, enabled: Boolean = true) = composed {
clickable(enabled = enabled && LocalGesturesEnabled.current.value, onClick)
}
但它不适用于第三方可组合项或更复杂的可组合项,例如 LazyList
。
我认为缺少此类系统修饰符的原因是您必须通过 enabled/disabled 控件使用不同状态或使用半透明覆盖视图向用户显示手势已禁用等
但技术上使用 pointerInput
modifier you can get all touch events with awaitPointerEvent
。
使用pass = PointerEventPass.Initial
参数,您将在所有子视图之前收到事件,然后您可以将事件标记为已处理consumeAllChanges
,这样子就不会再收到它们。
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::consumeAllChanges)
}
}
}
} else {
Modifier
}
如果您想了解有关自定义手势处理的更多信息,请查看this article
是否有内置 Modifier
禁用其子项的任何手势检测/指针输入交互?
例如
@Composable
fun Foo() {
Box(modifier = Modifier.gesturesEnabled(enabled = false)) {
BasicText(text = "Hello", modifier = Modifier.clickable { // clickable is not enabled
// ...
})
}
}
我可以使用 CompositionLocal
:
val LocalGesturesEnabled = compositionLocalOf { mutableStateOf(true) }
fun Modifier.myClickable(onClick: () -> Unit, enabled: Boolean = true) = composed {
clickable(enabled = enabled && LocalGesturesEnabled.current.value, onClick)
}
但它不适用于第三方可组合项或更复杂的可组合项,例如 LazyList
。
我认为缺少此类系统修饰符的原因是您必须通过 enabled/disabled 控件使用不同状态或使用半透明覆盖视图向用户显示手势已禁用等
但技术上使用 pointerInput
modifier you can get all touch events with awaitPointerEvent
。
使用pass = PointerEventPass.Initial
参数,您将在所有子视图之前收到事件,然后您可以将事件标记为已处理consumeAllChanges
,这样子就不会再收到它们。
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::consumeAllChanges)
}
}
}
} else {
Modifier
}
如果您想了解有关自定义手势处理的更多信息,请查看this article