android view事件OnTouch重複觸發
程式碼:
img.setOnTouchListener(
object : View.OnTouchListener{
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
var intent = Intent(
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方法(比如禁用等)