如何在onTouchEvent()中区分移动和点击?

84

在我的应用程序中,我需要处理移动和点击事件。

一个点击事件是由一个ACTION_DOWN事件、多个ACTION_MOVE事件和一个ACTION_UP事件组成的序列。理论上,如果你获取了一个ACTION_DOWN事件然后是一个ACTION_UP事件 - 这意味着用户刚刚单击了你的View。

但在实践中,这种序列在某些设备上不起作用。在我的三星Galaxy Gio手机上,当我只点击我的View时,我得到这样的序列: ACTION_DOWN, 多次ACTION_MOVE, 然后是ACTION_UP。也就是说,我会得到一些意外的带有ACTION_MOVE操作码的OnTouchEvent触发。我从来没有(或者几乎没有)得到过序列ACTION_DOWN -> ACTION_UP。

我也无法使用OnClickListener,因为它不提供点击位置。那么我该如何检测点击事件并将其与移动事件区分开来?


你尝试使用onTouch而不是onTouchEvent了吗?这样做可以让你引用到视图,从而记录值并查看是否调用了ACTION_DOWN和ACTION_UP的点击事件。 - Arif Nadeem
11个回答

0
与其使用基于距离/时间差的方法,您可以结合使用GestureDetectorsetOnTouchListener来实现此目的。GestureDetector将检测单击事件,而您可以使用OnTouchListener来处理其他触摸事件,例如拖动。
以下是参考示例代码:
Class MyCustomView() {

    fun addClickAndTouchListener() {
        val gestureDetector = GestureDetector(
            context,
            object : GestureDetector.SimpleOnGestureListener() {
                override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
                    // Add your onclick logic here
                    return true
                }
            }
        )

        setOnTouchListener { view, event ->
            when {
                gestureDetector.onTouchEvent(event) -> {
                    // Your onclick logic would be triggered through SimpleOnGestureListener
                    return@setOnTouchListener true
                }
                event.action == MotionEvent.ACTION_DOWN -> {
                    // Handle touch event
                    return@setOnTouchListener true
                }
                event.action == MotionEvent.ACTION_MOVE -> {
                    // Handle drag
                    return@setOnTouchListener true
                }
                event.action == MotionEvent.ACTION_UP -> {
                    // Handle Drag over
                    return@setOnTouchListener true
                }
                else -> return@setOnTouchListener false
            }
        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接