Touch 事件相關方法 |
方法功能 |
ViewGroup |
Activity View |
public boolean dispatchTouchEvent(MotionEvent ev) |
事件分發 |
Yes | Yes Yes |
public boolean onInterceptTouchEvent(MotionEvent ev) |
事件攔截 |
Yes | No No |
public boolean onTouchEvent(MotionEvent ev) |
事件響應 |
Yes | Yes Yes |
一、view的事件分發
搞清楚下面幾個方法關係就ok了,相對ViewGroup的分發還比較簡單
dispatchTouchEvent、onTouchEvent、onTouch
view的源碼:
- public boolean dispatchTouchEvent(MotionEvent event) {
- if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
- mOnTouchListener.onTouch(this, event)) {
- return true;
- }
- return onTouchEvent(event);
- }
看view的分發代碼
第一個條件mOnTouchListener是在setOnTouchListener方法裏賦值的,也就是說只要我們給控件註冊了touch事件,mOnTouchListener就一定被賦值了。第二個條件(mViewFlags & ENABLED_MASK) == ENABLED是判斷當前點擊的控件是否是enable的,按鈕默認都是enable的,因此這個條件恆定爲true。
第三個條件就比較關鍵了,mOnTouchListener.onTouch(this, event),其實也就是去回調控件註冊touch事件時的onTouch方法。也就是說如果我們在onTouch方法裏返回true,就會讓這三個條件全部成立,從而整個方法直接返回true。如果我們在onTouch方法裏返回false,就會再去執行onTouchEvent(event)方法。
其實大致就是這樣,觸摸一個view就會先有Down事件,然後執行dispatchTouchEvent(),而如果註冊onTouch接口監聽,那麼他其實最先會調用onTouch方法而不是onTouchEvent。若是onTouch返回true那就沒有onTouchEvent什麼事了,而若是false就會去調用onTouchEvent方法了,若是onTouchEvent返回true,dispatchTouchEvent也會返回true,就代表該view消費了此事件,接下來的Move、Up事件也會有他處理,若是onTouchEvent返回false,則dispatchTouchEvent也會返回false,於是就會把事件還給上一級view的onTouchEvent,接下來就不重要了,因爲這隻講view的分發。然後要說的就是比如類似onClick這些方法,都是接口回調嘛,這些也就是在onTouchEvent裏面調用的,具體自己看源碼,所以這也就說明onTouch先於onClick執行。
二、ViewGroup事件分發(這個很亂,待續)
1.相關方法分發邏輯
dispatchTouchEvent
*return super.dispatchTouchEvent(ev):事件自動分發給當前view的onInterceptTouchEvent或者onTouchEvent
*return true:事件停止向下傳遞,並分發給當前view由dispatchTouchEvent進行消費
*return false:事件停止向下傳遞,返回給上一級的onTouchEvent
onInterceptTouchEvent
*return super.onInterceptTouchEvent(ev):事件默認被攔截,將事件交由當前view的onTouchEvent進行處理
*return true:攔截掉子view的事件,將事件交由該view的dispatchTouchEvent進行處理
*return false:事件放行,當前view上的事件會傳到子view,再由子view的dispatchTouchEvent進行分發
onTouchEvent
*return super.onInterceptTouchEvent(ev):默認處理事件的邏輯和返回 false 時相同
*return true:表示它是真正要處理這次請求的View,之後的Aciton_UP和Action_MOVE將由它處理
*return false:事件從當前view向上傳遞,並且都由上層view的onTouchEvent接收,如果都返回false,則這個事件會 消失,就接收不到下一次事件。
2. dispatchTouchEvent
ViewGroup的dispatchTouchEvent方法真正執行分發工作,,而view的dispatchTouchEvent不再分發,直接決定是否把事件交給自己處理。