【问题标题】:ACTION_UP is not triggered for a quick/normal click on OnTouchListener.onTouch对 OnTouchListener.onTouch 的快速/正常点击不会触发 ACTION_UP
【发布时间】:2020-07-05 11:41:27
【问题描述】:

我有一个按钮来触发 MainActivity 中的某些操作,我想绘制动画如下:当用户按住按钮 (ACTION_DOWN) 时它会缩小,当按钮释放时 (ACTION_UP 或 ACTION_CANCEL) 它会放大并返回恢复到正常状态。

当用户按住按钮一段时间时,这很有效,但对于正常点击,即使 ACTION_DOWN 调用,ACTION_UP 也不会被调用。

我在文档中搜索并检查了 stackoverflow 上的几乎所有答案,但没有发现任何有用的信息。

documentation 是这样说的:“虽然框架试图将一致的运动事件流传递给视图,但它不能保证这一点。某些事件可能会在传递之前通过在应用程序中包含视图而被删除或修改,从而使事件流不一致。视图应始终准备好处理 ACTION_CANCEL,并应容忍异常情况,例如在没有先收到前一个手势的 ACTION_UP 的情况下接收到新的 ACTION_DOWN。"

这是我的代码:

button.setOnTouchListener { view, event ->
            when(event?.action){
                //behaves as expected
                MotionEvent.ACTION_DOWN -> {
                    scaleDown(view)
                }
                //the problem here: ACTION_UP gets called only when user holds the button for some time
                //and not for a quick/ normal click.
                MotionEvent.ACTION_UP -> {
                    scaleUp(view)
                    doSomething()
                }
                //behaves as expected
                MotionEvent.ACTION_CANCEL -> {
                    scaleUp(view)
                }
            }
            true
        }

我有两个问题,第一:为什么 ACTION_UP 永远不会被调用来进行快速/正常点击?

第二:如果我想以两种不同的方式做出反应,如何区分正常点击和用户按住按钮一段时间?

【问题讨论】:

    标签: android android-studio touch-event ontouchlistener


    【解决方案1】:

    问题#1

    我尝试了下面的 sn-p,它按预期工作,长时间、正常和快速点击

    button.setOnTouchListener { view, event ->
    
        if (event.action == MotionEvent.ACTION_DOWN) {
            Log.d("TESTOOO", "DOWN")
        } else if (event.action == MotionEvent.ACTION_UP) {
            Log.d("TESTOOO", "UP")
        }
    
        true
    }
    

    问题#2

    你能试试setOnLongClickListener()吗,我试过了,效果很好

    【讨论】:

    • 谢谢!问题在于动画不在触摸监听器上。
    【解决方案2】:

    回答我自己的问题:

    对于第一个问题,问题出在动画而不是 OnTouchListener。

    对于第二个问题,为了区分正常点击和长时间点击,我必须计算在触发 ACTION_UP 或 ACTION_CANCEL 时触发 ACTION_DOWN 已经过去了多少毫秒。

    如果两个事件之间的差异小于 300 毫秒,则视为正常点击,否则视为长点击。

    button.setOnTouchListener { view, event ->
        val now = System.currentTimeMillis()
        when(event?.action){
            MotionEvent.ACTION_DOWN -> {
                scaleDown(view)
            }
            MotionEvent.ACTION_UP -> {
                 scaleUp(view)
                 if(now - event.downTime < 300){
                     //normal click
                 }else{
                     //long click
                 }
            }
            MotionEvent.ACTION_CANCEL -> 
                 scaleUp(view)
            }
       }
       true
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 2018-11-14
      • 1970-01-01
      • 2011-07-22
      相关资源
      最近更新 更多