安卓的Touch事件傳遞處理主要與三個方法有關肌割,分別為
- 傳遞——dispatchTouchEvent()函數(shù)步做、
- 攔截——onInterceptTouchEvent()函數(shù)晌杰、
- 消費——onTouchEvent()函數(shù)
其調用順序與上述一致铸磅,其中onInterceptTouchEvent函數(shù)只有ViewGroup才有
借用網上的兩張圖片
主要內容就是:
1.事件通過dispatch函數(shù)向下傳遞缀遍,通過onTouch函數(shù)向上冒泡
2.當onTouch函數(shù)返回true時慕匠,表示事件被消費,從而使事件不再向上冒泡
3.當onInterceptTouchEvent函數(shù)返回true時域醇,表示阻止事件的向下傳遞台谊,如果當前view不消費事件,則事件會從當前層次在onTouch向上冒泡
4.當某一層View 的action_down事件不消費時譬挚,該view就不會收到后續(xù)的move和up事件
網上資料都說锅铅,onTouch返回true表示消費事件,onInterceptTouchEvent返回true表示攔截事件减宣,onDispatchEvent返回true又表示什么盐须?這三個返回值相互之間有什么制約呢?當我重載他們并通過打log發(fā)現(xiàn)漆腌,log信息并不是我想象中的那樣
實驗前:
- 所有的層的dispatchTouchEvent都直接調用父類的方法 return super.dispatchTouchEvent( )丰歌,后面的測試在不說明的情況下這是默認的做法
- 除非特別說明姨蟋,否則所有的onInterceptTouchEvent方法都緊跟著dispatch方法后被調用,圖里不再標示
- “調用super立帖,但直接返回false” ,意思是在代碼中
super.xxxxEvent();
return false;
而不是return super.xxxEvent();
例一
討論分析
- ViewGroup的interceptTouchEvent緊跟著dispatchTouchEvent之后調用, intercept和ontouch默認情況下返回false;
- View和viewgroup在不消費action_down事件的情況下悠砚,不會觸發(fā)后續(xù)的action_move晓勇、action_up等事件
- activity即使不消費action_down事件,依然會在兩個方法中收到move和up事件
例二(也是比較常見的情況)
討論分析
- View在onTouch消費了所有事件灌旧,所以只有View的onTouch方法被調用绑咱,事件不向上傳遞。情況簡單枢泰,不多述
例三(開始不太正常)
討論分析
- ViewGroup2之上的所有的intercep方法會被調用(這個例子中是指viewgroup的intercept描融,同樣是跟在dispatch之后),但ViewGroup2的Intercep方法不會調用
- 所有的onTouch方法不會被調用
例4
討論分析
當我們不在dispatch方法中調用super且直接返回false時衡蚂,事件傳遞邏輯就變得有點亂
- ViewGroup2的onTouch不被調用窿克,但onTouch事件能從上一層開始正常冒泡
- 由于action_down不消費,則后續(xù)事件不再傳下來
總結
- activity的onTouch和dispatch方法無論任何事件毛甲、事件是否被消費都會被調用
- 這三個方法的調用并不是我們想像中的獨立的線性關系年叮,而是調用與被調用的關系,onTouch和onIntercept方法其實是在view的dispathTouchEvent方法中被調用的玻募,而且dispathTouchEvent的返回值參考了onTouch的返回值只损,如果我們重載dipatch時不調用super.dispatch,則這個view的onTouch七咧、onIntercept方法不會被調用
- super.dispathTouchEvent的返回值與onTouch的返回一致跃惫,onTouch返回true之所以能阻止事件向上傳遞是因為其使得dispathTouchEvent也返回了true。這時如果你重載dispathTouchEvent強制返回false艾栋,依然無法阻止事件向上冒泡
- 要使事件向下傳遞爆存,必需在dispatch中調用super.dispatch(如果你重載它的話),如果不調用super裹粤,就代表截攔事件终蒂,但不代表消費事件,因為這時onTouch不會被調用遥诉,無法消費拇泣,但事件會從上一層開始在onTouch中向上冒泡,如 例4