Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 区分短按(点击)和长按(点击)_Android_Kotlin_Ontouchlistener - Fatal编程技术网

Android 区分短按(点击)和长按(点击)

Android 区分短按(点击)和长按(点击),android,kotlin,ontouchlistener,Android,Kotlin,Ontouchlistener,我已经找到了这个答案: 但我对你感兴趣。原因是,我希望短按并释放(单击)将触发特定行为,但长按(不释放)将触发运动事件,使用户能够用手指拖动小部件 所以我使用的是ACTION_MOVE: val listener = View.OnTouchListener(function = { view, motionEvent -> // check if the user gesture upon the view is of moving action when (motion

我已经找到了这个答案: 但我对你感兴趣。原因是,我希望短按并释放(单击)将触发特定行为,但长按(不释放)将触发运动事件,使用户能够用手指拖动小部件

所以我使用的是ACTION_MOVE:

val listener = View.OnTouchListener(function = { view, motionEvent ->
    // check if the user gesture upon the view is of moving action
    when (motionEvent.action) {
        MotionEvent.ACTION_DOWN-> {
            // pressed
        }
        MotionEvent.ACTION_MOVE -> {
            view.y = motionEvent.rawY - ((view.height / 2) + 60)
            view.x = motionEvent.rawX - view.width / 2
        }
        MotionEvent.ACTION_UP -> {
            // Released

问题是动作会立即触发。是否有一个选项仅在长按时调用它?我想也许可以使用时间戳来启用和禁用它,但有没有更简单的解决方案?

Android处理这个问题的方法是使用手势检测器。指南主题讨论了如何执行此操作,并提供了示例代码

您希望在触摸式监听器的相对较低级别上操作的唯一原因是,您想要实现的逻辑尚未由某个库手势检测器打包。幸运的是,长按和拖动已经是受支持的手势

如果您想编写自己的逻辑,那么适当的手势检测器的源代码可以为您提供一个良好的起点。但是,我强烈反对这样做,因为逻辑可能非常复杂,有很多边缘情况需要纠正

编辑:好的,在阅读了文档之后,我承认它并不像我想象的那么简单。但也不应该很复杂。从for
设置IsLongPress Enabled
中可以清楚地看到问题(添加了重点):

设置是否启用longpress,如果在用户按住时启用此选项,则会出现longpress事件,且不会出现任何其他事件

因此,在检测到长按后,您将不会收到任何滚动回拨。您可以按如下方式解决此问题。使用手势检测器的常用方法是将
onTouchEvent
方法编写如下:

override fun onTouchEvent(event: MotionEvent): Boolean {
    return if (mDetector.onTouchEvent(event)) {
        true
    } else {
        super.onTouchEvent(event)
    }
}
您可以将其更改为以下内容:

var isLongPress = false

override fun onTouchEvent(event: MotionEvent): Boolean {
    if (mDetector.onTouchEvent(event)) {
        val action = MotionEventCompat.getActionMasked(event)
        if (isLongPress && action == MotionEvent.ACTION_MOVE) {
            // process the drag
        }    
        return true
    }
    return super.onTouchEvent(event)
}

然后在
onLongPress
回调中,捕获事件坐标并设置
isLongPress
。您可以在
onDown
回拨中清除
isLongPress
。然后,您应该忽略对
onScroll
的任何回拨,因为根据定义,它们将在不长时间按下的情况下发生。

非常感谢,我正在研究它,这似乎是一个非常简单的解决方案你好,Ted,我只想在这里写道,虽然手势检测器对简单的作业很有帮助,它相当有限,不灵活。例如,长按事件后无法检测滚动/拖动事件,长按将阻止任何其他事件,并且此行为无法更改。看来,它直接编辑GestureDetector.java或不使用it@sir-哈弗-你的意思是,在手势检测器调用听者的
onLongPress
方法后,它不会调用
onScroll
?这有点令人惊讶。如果是这种情况,请告诉我,我可能会有一两个建议。嘿,Ted,我的意思是相反的:在手势检测器调用听者的onLongPress方法后,它将调用onScroll(如果用户在长按的同时移动手指)。目前,onLongPress方法阻止了onScroll方法——如果我没有弄错的话,我可以在GestureDetector.java中看到这种阻止,因此当调用onLongPress时,无法调用onScroll。“有可能改变这种默认行为吗?”哈弗爵士-这难道不是你想要的——长按后拖动吗?您可以使用
onLongPress
回调设置标志,然后忽略滚动,除非设置了标志。(您可以清除启动任何手势的
onDown
回调中的标志。)