Jetpack Compose:着陆后不捕获所有触摸事件

Jetpack Compose: do not capture all touch events after touch down

提问人:Maarten 提问时间:10/11/2023 最后编辑:Maarten 更新时间:10/12/2023 访问量:151

问:

假设在 Jetpack Compose 中,有一行 5 个按钮。出于我的目的,我希望用户能够触摸第一个按钮,沿着行按钮滑动手指,从另一个按钮抬起,并为手指抬起的按钮触发单击侦听器,同时还触发指示在此过程中触摸的所有按钮。

似乎 Modifier.clickable 总是捕获该组件的所有触摸事件,直到所有指针都向上,所以我想我可以提升 MutableInteractionSource 并从父组件上的低级指针事件回调发送按下/发布事件,计算我们是否将鼠标悬停在子组件上,并适当地发送推送/释放事件。这确实会触发指示,但仅发出事件显然不会触发侦听器。所以这没有用。InteractiononClick

最后,我决定放弃 ,只从父可组合项 (through ) 发出合成的 Press 和 Release 事件,然后从每个按钮的 MutableInteractionSource 收集交互流,并在我们获得 Release 事件时运行相应的 lambda。clickableawaitEachGestureonClick

visual representation

这似乎像我预期的那样工作,但也感觉有点骇人听闻/脆弱/错误。我觉得这个解决方案可能缺少很多辅助功能,或者至少缺少一些东西,因为它基本上放弃了所有代码,只是监听指针向上/向下,然后将其转发到子组件。相比之下,它的实现真的非常复杂:我完全不明白那里发生了什么。但是我想利用基础中的所有代码(使 bitton 可通过语义/选项卡可访问/响应键盘事件等),如果可能的话,我的特定用途。Modifier.clickableModifier.clickable

安卓 android-jetpack-compose onclicklistener 触摸事件 android-touch-event

评论

0赞 Pawel 10/11/2023
在本机运动事件场景中,在不先触摸手指的情况下将手指“抬起”到视图上方不被视为单击,因此我怀疑您可以在这种情况下使用可单击的修饰符。
0赞 Maarten 10/11/2023
@Pawel这就是为什么当手指进入视图时,我会合成地发出 Press 事件。但 clickable 显然不会在基于 Interaction 事件的点击时触发
0赞 Thracian 10/11/2023
@Maarteen Modiifer.clickable 在调用 awaitFirstDown 时触发 Press 事件。你应该在源代码中寻找的是函数detectTapAndPress
1赞 Thracian 10/11/2023
那好吧。这是唯一可能的解决方案。正如您在源代码中看到的,按 depends 仅在第一个指针按下后才会触发。这也是调用 .如果你看一下功能,可点击的代码实际上非常简单。awaitFirstDownawaitPointerEventif (requireUnconsumed) it.changedToDown() else it.changedToDownIgnoreConsumed()detectTapAndPress
1赞 Thracian 10/11/2023
因为它派生自 View 手势代码和 jetpack 中的修饰符,所以 Compose 是节点元素。这就是数据结构,可点击的手势实现是 detectTapAndPress,指示为“handlePressInteraction(offset)”。如果单击 Modifier.size(),您将看到它也包含 Node 元素源代码。

答: 暂无答案