Jetpack Compose:如何禁用儿童手势检测 [英] Jetpack Compose: how to disable gesture detection on children

查看:38
本文介绍了Jetpack Compose:如何禁用儿童手势检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有内置的 Modifier 可以禁用其子项的任何手势检测/指针输入交互?

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

例如

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

我可以使用 CompositionLocal 推出我自己的(非常简单的)实现:

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)
}

但它不适用于第三方组合件或更复杂的组合件,例如 LazyList.

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

推荐答案

我认为缺少这样一个系统修饰符的原因是你必须通过对启用/禁用控件使用不同的状态来向用户展示手势被禁用,或使用半透明的叠加视图等.

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.

但技术上使用 pointerInput 修饰符你可以通过 awaitPointerEvent.

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

使用 pass = PointerEventPass.Initial 参数,您将在所有子视图之前接收事件,然后您可以将事件标记为使用 consumeAllChanges 处理,以便子视图不再接收它们.

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) =
    pointerInput(disabled) {
        // if gestures enabled, we don't need to interrupt
        if (!disabled) return@pointerInput

        awaitPointerEventScope {
            // we should wait for all new pointer events
            while (true) {
                awaitPointerEvent(pass = PointerEventPass.Initial)
                    .changes
                    .forEach(PointerInputChange::consumeAllChanges)
            }
        }
    }

如果您想了解有关自定义手势处理的更多信息,请查看 这篇文章

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

这篇关于Jetpack Compose:如何禁用儿童手势检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆