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