基于Android version 26 的源碼對Android 事件傳遞進(jìn)行分析
1 基礎(chǔ)分析
1)Activity 處理事件的源碼如下:
源碼分析:Activity 收到系統(tǒng)事件就會調(diào)用 diapatchTouchEvent(ex)處理
在diapatchTouchEvent方法內(nèi)部 調(diào)用 Activity 的 對應(yīng)的 PhoneWindow的?
superDiapatchTouchEvent(ex)來處理
2)phoneWindow 處理事件源碼:
DecorView 的 處理源碼和DecorView 的定義:
源碼分析:
1)PhoneWindow 的superDispatchTouchEvent內(nèi)部調(diào)用DecorView的?superDispatchTouchEvent
2)DecorView 的?super.dispatchTouchEvent(event); 內(nèi)部調(diào)用?super.dispatchTouchEvent(event);
3) DecorView 是繼承自 FrameLayout 實(shí)際調(diào)用的是 ViewGroup 的?dispatchTouchEvent(event);
3) ViewGroup 的 事件處理源碼:
源碼分析:
1) 接著就是查找當(dāng)前的 focus child view 由外向里 傳遞事件,調(diào)用 child 的?dispatchTouchEvent
2)同時還有一個 intercepted 的 判斷, 如果 onInterceptTouchEvent返回 true 則intercepted=true, 那么事件就不會再向viewgroup的 子view 傳遞
????3) View group 里面如過 判斷 onInterceptTouchEvent 返回true 以后的code 邏輯:如果當(dāng)前沒有 TouchTarget 則當(dāng)前的ViewGroup 就是TouchTarget, 調(diào)用?dispatchTransformedTouchEvent 給當(dāng)前的view
在?dispatchTransformedTouchEvent 方法里面 會調(diào)用:handled = super.dispatchTouchEvent(event);?
讓 ViewGroup的 super 也就是 View 類來處理 這個event
也就是 如果onInterceptTouchEvent返回 true 則 這個view group 就會當(dāng)成一個 view 來handle event?
4) View group 如何向子View 傳遞 并且check 子view的返回值:
a )會遍歷所有的子view 并且判斷 是否在 事件 touch 區(qū)域,然后調(diào)用 在dispatchTransformedTouchEvent 中 調(diào)用?handled = child.dispatchTouchEvent(event);??
b) 在如果有child view?dispatchTouchEvent 返回 true 則在?addTouchTarget(child, idBitsToAssign); 設(shè)置?mFirstTouchTarget的值 為當(dāng)前child view。
如果 child view 返回 false,則mFirstTouchTarget 的值依然為 null? 默認(rèn)還是要調(diào)用 當(dāng)前view group 的?dispatchTransformedTouchEvent 和 onTouchEvent
4) View 事件處理源碼:
源碼分析:
1)view 調(diào)用dispatchTouchEvent 會先判斷?handleScrollBarDragging 和?li.mOnTouchListener.onTouch 如果這個兩個返回true則表明 view 已經(jīng)消費(fèi)了事件,將不會調(diào)用 onTouchEvent()
2)如果以上兩個不消費(fèi)事件 才調(diào)用?onTouchEvent()