繁体   English   中英

检测用户何时抬起手指(离开屏幕)

[英]Detect when the user lifts their finger (off the screen)

我们有用于检测点击、拖动和平移事件的pointerInput ,它还为移动设备提供了方便的awaitPointerEventScopepointer就是手指。 现在,我们确实有一个awaitFirstDown()用于检测手指何时第一次接触屏幕,但我似乎找不到与此方法等效的上层。

我有一个小部件,我希望检测点击,但问题是该应用程序是为这样一个用例制作的,用户在使用过程中可能处于奇怪的位置,所以我希望它触发所需的只需触摸并抬起手指即可进行操作。 偏执的是,用户可能会不小心“拖动”他们的手指(即使是一毫米,android 仍然会捡起它),我不希望出现这种情况。 我可以实现轻敲和拖动监听器,但据我所知,它们都没有提供手指抬起检测。

什么解决方案(如果目前有的话)适合用例,同时坚持和利用 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()

一个特殊的 PointerInputModifier,它提供对最初分派给 Compose 的底层 MotionEvent 的访问。 首选 pointerInput 并仅将其用于与使用 MotionEvents 的现有代码的互操作。 虽然此 Modifier 的主要目的是允许任意代码访问派发给 Compose 的原始 MotionEvent,但为了完整起见,提供了类似物以允许任意代码与系统交互,就好像它是一个 Android 视图一样。

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

这个答案详细解释了它的工作原理、内部原理和创建自己的手势时要考虑的关键点。

这也是一个 手势库,您可以使用 onGestureEnd 回调检查 onTouchEvent 对应项和 2 用于 detectTransformGestures,并在 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.consumeAllChanges()

PointerInputChange.consume()

是唯一用于防止其他手势/事件的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM