1. 程式人生 > >android view事件OnTouch重複觸發

android view事件OnTouch重複觸發

程式碼:

img.setOnTouchListener(
        object : View.OnTouchListener{
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                var intent = Intent(

[email protected], 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方法(比如禁用等)