【问题标题】:Jetpack Compose: how to disable gesture detection on childrenJetpack Compose:如何禁用儿童的手势检测
【发布时间】:2021-09-11 10:41:24
【问题描述】:

是否有内置的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

【问题讨论】:

    标签: gesture android-jetpack-compose


    【解决方案1】:

    我认为缺少这种系统修饰符的原因是您必须通过使用启用/禁用控件的不同状态或使用半透明覆盖视图等来向用户显示手势被禁用。

    但从技术上讲,使用pointerInput 修饰符您可以使用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

    【讨论】:

    • 如果我将此修饰符设置为主 BOX,我无法点击任何按钮
    • @saeednoshadi 是的,它的作用是阻止所有子视图中的任何可组合触摸。
    猜你喜欢
    • 2022-10-18
    • 1970-01-01
    • 2023-01-20
    • 2022-11-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多