检测用户何时抬起手指(离开屏幕)
Detect when the user lifts their finger (off the screen)
我们有 pointerInput
用于检测点击、拖动和平移事件,它还提供了方便的 awaitPointerEventScope
,pointer
是手指,适用于此处的移动设备。现在,我们确实有一个 awaitFirstDown()
用于检测手指何时首次接触屏幕,但我似乎找不到与此方法等效的上层方法。
我有一个小部件,我希望检测点击,但问题是该应用程序是为这样的用例而设计的,用户在使用过程中可能会处于奇怪的位置,所以我希望只需轻触和抬起手指,它就会触发所需的操作。偏执狂是用户可能不小心 'drag' 他们的手指(即使是一毫米,android 仍然会捡起它),我不希望出现这种情况。我可以实现点击和拖动侦听器,但据我所知,其中 none 提供手指抬起检测。
哪种解决方案(如果目前有的话)适合用例,同时坚持并利用 Compose 的声明性特性,同时将代码库保持在最低限度?
pointerInteropFilter
是要走的路
Item(
Modifier.pointerInteropFilter {
if (it.action == MotionEvent.ACTION_UP) {
triggerAction()
}
true // Consume touch, return false if consumption is not required here
}
)
更好的方法,如果您不使用与现有视图代码的互操作性,Android 代码建议的是 Modifier.pointerInput()
A special PointerInputModifier that provides access to the underlying
MotionEvents originally dispatched to Compose. Prefer pointerInput and
use this only for interoperation with existing code that consumes
MotionEvents. While the main intent of this Modifier is to allow
arbitrary code to access the original MotionEvent dispatched to
Compose, for completeness, analogs are provided to allow arbitrary
code to interact with the system as if it were an Android View.
val pointerModifier = Modifier
.pointerInput(Unit) {
forEachGesture {
awaitPointerEventScope {
awaitFirstDown()
// ACTION_DOWN here
do {
//This PointerEvent contains details including
// event, id, position and more
val event: PointerEvent = awaitPointerEvent()
// ACTION_MOVE loop
// Consuming event prevents other gestures or scroll to intercept
event.changes.forEach { pointerInputChange: PointerInputChange ->
pointerInputChange.consumePositionChange()
}
} while (event.changes.any { it.pressed })
// ACTION_UP is here
}
}
}
详细解释了它的工作原理、内部结构和创建您自己的手势时要考虑的要点。
这也是一个 gesture library 您可以检查 onTouchEvent 对应物和 2 个带有 onGestureEnd 回调的 detectTransformGestures 和 returns 向下指针数或 onGesture 事件中的 PointerInputChange 列表。可以用作
Modifier.pointerMotionEvents(
onDown = {
// When down is consumed
it.consumeDownChange()
},
onMove = {
// Consuming move prevents scroll other events to not get this move event
it.consumePositionChange()
},
onUp= {}
delayAfterDownInMillis = 20
)
编辑
截至 1.2.0-beta01,部分消耗类似
PointerInputChange.consemePositionChange()
,
PointerInputChange.consumeDownChange()
,以及一个用于消耗所有更改的 PointerInputChange.consumeAllChanges()
已弃用
PointerInputChange.consume()
是唯一用来防止其他 gestures/event.
的
我们有 pointerInput
用于检测点击、拖动和平移事件,它还提供了方便的 awaitPointerEventScope
,pointer
是手指,适用于此处的移动设备。现在,我们确实有一个 awaitFirstDown()
用于检测手指何时首次接触屏幕,但我似乎找不到与此方法等效的上层方法。
我有一个小部件,我希望检测点击,但问题是该应用程序是为这样的用例而设计的,用户在使用过程中可能会处于奇怪的位置,所以我希望只需轻触和抬起手指,它就会触发所需的操作。偏执狂是用户可能不小心 'drag' 他们的手指(即使是一毫米,android 仍然会捡起它),我不希望出现这种情况。我可以实现点击和拖动侦听器,但据我所知,其中 none 提供手指抬起检测。
哪种解决方案(如果目前有的话)适合用例,同时坚持并利用 Compose 的声明性特性,同时将代码库保持在最低限度?
pointerInteropFilter
是要走的路
Item(
Modifier.pointerInteropFilter {
if (it.action == MotionEvent.ACTION_UP) {
triggerAction()
}
true // Consume touch, return false if consumption is not required here
}
)
更好的方法,如果您不使用与现有视图代码的互操作性,Android 代码建议的是 Modifier.pointerInput()
A special PointerInputModifier that provides access to the underlying MotionEvents originally dispatched to Compose. Prefer pointerInput and use this only for interoperation with existing code that consumes MotionEvents. While the main intent of this Modifier is to allow arbitrary code to access the original MotionEvent dispatched to Compose, for completeness, analogs are provided to allow arbitrary code to interact with the system as if it were an Android View.
val pointerModifier = Modifier
.pointerInput(Unit) {
forEachGesture {
awaitPointerEventScope {
awaitFirstDown()
// ACTION_DOWN here
do {
//This PointerEvent contains details including
// event, id, position and more
val event: PointerEvent = awaitPointerEvent()
// ACTION_MOVE loop
// Consuming event prevents other gestures or scroll to intercept
event.changes.forEach { pointerInputChange: PointerInputChange ->
pointerInputChange.consumePositionChange()
}
} while (event.changes.any { it.pressed })
// ACTION_UP is here
}
}
}
这也是一个 gesture library 您可以检查 onTouchEvent 对应物和 2 个带有 onGestureEnd 回调的 detectTransformGestures 和 returns 向下指针数或 onGesture 事件中的 PointerInputChange 列表。可以用作
Modifier.pointerMotionEvents(
onDown = {
// When down is consumed
it.consumeDownChange()
},
onMove = {
// Consuming move prevents scroll other events to not get this move event
it.consumePositionChange()
},
onUp= {}
delayAfterDownInMillis = 20
)
编辑
截至 1.2.0-beta01,部分消耗类似
PointerInputChange.consemePositionChange()
,
PointerInputChange.consumeDownChange()
,以及一个用于消耗所有更改的 PointerInputChange.consumeAllChanges()
已弃用
PointerInputChange.consume()
是唯一用来防止其他 gestures/event.
的