Android中ViewGroup的事件分發結論記錄

這裏記錄一下關於ViewGroup中下發不一樣Action致使系統分發邏輯不一樣的總結,該總結創建在閱讀過事件分發的源碼上,若是沒有閱讀過源碼的話,不建議閱讀該篇文章。若是有總結不對的地方,但願各位同行可以指正,一塊兒進步~java

首先ViewGroup中的觸摸處理邏輯以下:spa

void dispatchTouchEvent(){
    if(onInterceptionTouchEvent()){
        onDraw();
    }else{
		child.disptachTouchEvent();
    }
}

當一個觸摸事件來臨的時候,首先由Activity接收到觸摸事件,而後下發至DecorView,DecorView中根據Z軸位置由上至下進行傳遞事件處理:rest

  • Activity -> DecorView -> ViewGroup ->....->View

當傳遞過程當中沒有任何View消費事件,那麼事件由View->ViewGroup->Activity逆序返回,最終的事件由Activity處理,若是View消費了事件,那麼則分爲兩種狀況,這兩種狀況能夠從代碼的角度中理解:code

public boolean dispatchTouchEvent(MotionEvent ev){
...
//1.
	if (actionMasked == MotionEvent.ACTION_DOWN
                    || mFirstTouchTarget != null) {
                final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    intercepted = onInterceptTouchEvent(ev);
                    ev.setAction(action); // restore action in case it was changed
                } else {
                    intercepted = false;
                }
            } else {
                intercepted = true;
            }
			//2.
	 if (!canceled && !intercepted){
				//傳遞事件,構造mFirstTouchTarget
				}

...
}
  • 當在ACTION_DOWN時攔截,第二步是不會走的,也就意味着mFirstTouchTarget=null,在隨後的事件來臨的時候,因爲mFirstTouchTarget==null,事件全權交由當前ViewGroup處理,子View就再也收不到觸摸事件了。
  • 當不在ACTION_DOWN時攔截,而且mFirstTouchTarget不爲空,那麼這個時候子View會收到一個ACITON_CANCEL事件,而後後續事件都由ViewGroup處理了。

那麼經過這種狀況,咱們得知,當咱們在處理滑動觸摸衝突的時候,不該該在父ViewGroup中進行ACTION_DOWN的攔截操做,若是攔截了,子View根本不可能受到觸摸事件;另外當父ViewGroup攔截中攔截了ACTION_MOVE操做後,實際上子View是會收到一個CANCALE事件的,經過該事件,咱們能在子View中進行一些善後的處理。事件

相關文章
相關標籤/搜索