我正在努力为我的应用程序创建“入门”体验,这本质上是有关如何使用该应用程序的快速指南。为了实现这一目标,我希望用户单击应用程序指示他们的位置。具体来说,我想创建一个用户界面,其中包含允许用户单击的圆形元素和不允许单击的灰色透明背景(为了清楚起见,请参阅附图)
我当前的挑战在于弄清楚如何将此单击事件传播到较低的 UI 层。
这是相关的代码片段:
Canvas(
modifier = Modifier
.fillMaxSize()
.zIndex(3f)
.pointerInput(Unit) {
detectTapGestures(onTap = { offset ->
if (!Rect(position, volume).contains(offset)) {
Log.d("app-debugger9","Cancel the click!")
}
else
{
Log.d("app-debugger9","Propagate click to below UI layers!")
}
})
}
) {
val circlePath = Path().apply {
addOval(Rect(position, volume))
}
clipPath(circlePath, clipOp = ClipOp.Difference) {
drawRect(SolidColor(Color.Black.copy(alpha = alphaValue)))
}
}
Log.d(“app-debugger9”,“将单击传播到较低的 UI 层!”) - 此 Log.d 语句指示我打算将单击事件传播到较低的 UI 层的时刻。我的问题是:我怎样才能实现这一目标?
目前,无论我单击圆内还是圆外的位置,我都无法将该单击传播到较低的 UI 层。
我期望的是,如果我在圆圈外单击,则该单击将被忽略。但是,如果我在圆圈内部单击,则单击会传播到较低的 UI 层,从而导致打开关卡(因为该圆圈位于关卡打开按钮上方)。
注意:1)不使用“pointerInput(Unit)”也可以完成此操作,但我不确定如何做到这一点,所以我现在选择使用“pointerInput(Unit)”。2) 当我引用“上方”或“下方”UI 层时,我使用的是 .zIndex()。如果指数较大,则表示“高于”,如果指数较小,则表示“较低”。
使用 Modifier.clickable 或 PointerEventScope.detectTapGestures,您无法将手势传播到后代或父级,因为它们调用
PointeEventChange.consume()
,您可以查看有关Jetpack Compose 中的手势和手势传播的答案。但就您而言,您似乎正在尝试将事件传播到不可能的位置,在我看来,这是一个糟糕的设计。对于任何想要将手势传递给父母而不是兄弟姐妹的人,您可以使用 轻松编写自定义上下检测手势
awaitEachGesture
。根据 Box1 和 Box2 的 zIndex,您将看到 zIndex 较大的一个将触发事件,如果默认情况下均为零,则将为第二个 Box 触发事件,然后传播到父级。您可以通过食用其中任何一个来选择性地改变这一点
PointerInputChange
。在 OP 情况下,不需要第二个 Box。可以使用 Modifier.drawWithContent 绘制带有圆形剪辑的黑色透明层,并根据触摸位置触发该层或任何组件中的单击事件。
您可以看到,虽然点击手势被消耗,但除非您消耗手势,否则它们会被传播。