android view事件OnTouch重复触发

代码:

img.setOnTouchListener(
        object : View.OnTouchListener{
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                var intent = Intent(this@OneActivity, TwoActivity::class.java)
                startActivity(intent)
                return true
            }
        }
)

 

先讲解一个东西:

Android的触摸事件:
Android 的触摸事件分为两类:

1、down - up      

2、down-move-up  ,所谓的down就是按下手指,move就是移动手指,up就是松开手指


我们使用手机,每次点击屏幕的时候,都会触发这两种事件之一:

1、按下手指 ,然后松开手指   

2、按下手指,移动,然后松开手指。这个时候我们就可以解释一件事了,平时我们点击某个按钮,必须是松开手指才会跳转,并且在此期间,你手指滑动到按钮外,也不会触发点击事件。

Android中把触摸事件封装成了一个类MotionEvent,用户的一次点击、触摸或者滑动都会产生一系列的MotionEvent
这个类的内容很简单,就两个东西:事件类型+坐标xy
事件类型有四种
MotionEvent.ACTION_DOWN 表示用户的手指刚接触到屏幕
MotionEvent.ACTION_MOVE 表示用户的手指正在移动
MotionEvent.ACTION_UP 表示用户的手指从屏幕上抬起
MotionEvent.ACTION_CANCEL

OnTouch重复触发的原因:

Android基于Touch的事件分发机制为当return true时,表示会由该控件消费该事件,会把该触控事件分发出去,这就导致到MotionEvent.ACTION_DOWN 、MotionEvent.ACTION_MOVE 、MotionEvent.ACTION_UP 、MotionEvent.ACTION_CANCEL(如果触发,一般触控一下只触发前三个)四个事件都调用一次onTouch,这时候OnTouch重复触发。

解决方法:

return true时,可以通过when(case)语句去分别处理这四个事件,

override fun onTouch(v: View?, event: MotionEvent?): Boolean {
    when(event?.action){
        MotionEvent.ACTION_DOWN -> {
          Log.e("MotionEvent","ACTION_DOWN")
        }
        MotionEvent.ACTION_MOVE -> {
            Log.e("MotionEvent","ACTION_MOVE")
        }
        MotionEvent.ACTION_UP -> {
            Log.e("MotionEvent","ACTION_UP")
        }
        MotionEvent.ACTION_CANCEL -> {
            Log.e("MotionEvent","ACTION_CANCEL")
        }
    }

或者

return false,这时候,触控只会调用一次基于MotionEvent.ACTION_DOWN事件的onTouch方法体。

补充:

一开始是想使用img.setOnClickListener去实现功能的,但是在方法体内局部的声明img.setOnClickListener时,

会因为onTouch方法影响了它而导致单击事件无效,解决方法为使用setOnTouchListener取代setOnClickListener

或者屏蔽掉onTouch方法(比如禁用等)

猜你喜欢

转载自blog.csdn.net/qq_39587209/article/details/86065107