二.ViewGroup事件分發(fā)源碼分析之事件處理

關(guān)鍵源碼(對dispatchTouchEvent()的重要部分)

片段一 是否攔截事件

 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 {
        // There are no touch targets and this action is not an initial down
        // so this view group continues to intercept touches.
         intercepted = true;
    }

片段二 如果ViewGroup不攔截事件


if (!canceled && !intercepted) {
 for(遍歷child){
  if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
        newTouchTarget = addTouchTarget(child, idBitsToAssign);
        break;
  }
 }
}

片段三 有無Child處理事件

if (mFirstTouchTarget == null) {
  // No touch targets so treat this as an ordinary view.
          handled = dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);
}else{
// dispatched to it.  Cancel touch targets if necessary.
         TouchTarget predecessor = null;
         TouchTarget target = mFirstTouchTarget;
         while (target != null) {
                final TouchTarget next = target.next;
                if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
                        handled = true;
                } else {
                    final boolean cancelChild = resetCancelNextUpFlag(target.child)
                                || intercepted;//攔截時蠢熄,cancelChild為true
                    if (dispatchTransformedTouchEvent(ev, cancelChild,
                                target.child, target.pointerIdBits)) {
                            handled = true;
                    }
                    if (cancelChild) {
                        if (predecessor == null) {
                               mFirstTouchTarget = next;//會將mFirsrtTouchTarget置空
                        } else {
                                predecessor.next = next;
                        }
                        target.recycle();
                        target = next;
                        continue;
                        }
                }
                    predecessor = target;
                    target = next;
           }
           
           if (canceled
                    || actionMasked == MotionEvent.ACTION_UP
                    || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
                resetTouchState();
            } 
            
        }
    }
    

disallowIntercept 默認(rèn)值為false,通過viewGroup.requestDisallowInterceptTouchEvent(boolean)進(jìn)行設(shè)置。本文只討論disallowIntercept 為false的情況穗酥。
mFirstTouchTarget==null 沒有child處理事件护赊,有兩種可能

  1. ViewGroup攔截了事件
  2. ViewGroup沒有攔截了事件,但是沒有child處理事件

mFirstTouchTarget!=null 有child處理事件

  1. ViewGrop沒有攔截事件砾跃,且有child消費了事件

intercepted表示是否攔截事件,值為true表示攔截事件节吮。

對ACTION_DOWN事件的處理

  1. 由onInterceptTouchEvent()判斷是否攔截(片段一)
  2. 如果ViewGroup攔截事件抽高,則遍歷child,將事件交給child處理,如果有child消耗了事件透绩,則調(diào)用addTouchTarget()給mFirstTouchTarget賦值翘骂。(片段二)
  3. 如果child不消費ACTION_DWON(mFirstTouchTarget==null),則ViewGroup處理該ACTION_DOWN事件。(片段三)

對ACTION_MOVE事件的處理

  1. 如果有child消費正在處理事件( mFirstTouchTarget != null),則由onInterceptTouchEvent()判斷是否攔截帚豪,否則攔截事件(片段一)
  2. 如果ViewGroup攔截ACTION_MOVE事件碳竟,則遍歷child,將事件交給child處理,如果有child消費了事件狸臣,則調(diào)用addTouchTarget()給mFirstTouchTarget賦值莹桅。(片段二)
  3. 如果沒有child消費正在處理事件(mFirstTouchTarget==null),則ViewGroup處理該ACTION_MOVE事件,否則 如果ViewGroup攔截了ACTION_MOVE,則mFirstTouchTarget設(shè)置為空烛亦。(片段三)

對ACTOIN_UP事件的處理

  1. 如果有child正在處理事件( mFirstTouchTarget != null)诈泼,則由onInterceptTouchEvent()判斷是否攔截,否則攔截事件(片段一)
  2. 如果ViewGroup攔截ACTION_UP事件,則遍歷child,將事件交給child處理,如果有child消耗了事件凳宙,則調(diào)用addTouchTarget()給mFirstTouchTarget賦值兴猩。(片段二)
  3. 如果沒有child正在消費事件,則ViewGroup處理該ACTION_MOVE事件卖漫,
    否則
    1. 如果ViewGroup攔截了ACTION_UP,則mFirstTouchTarget設(shè)置為空。
    2. 重置TouchState狀態(tài)

總結(jié)

ACTION_DWON作為起始動作,所以要判斷是否攔截

ACTION_MOVE,ACTION_UP作為后續(xù)事件
如果child在處理事件杭抠,ViewGroup要判斷是否攔截事件;
如果沒有child在處理事件知牌,ViewGroup自然攔截事件祈争。

如果ViewGroup不攔截事件,事件交給child處理角寸。

如果沒有Child正在處理事件菩混,則事件交給ViewGroup處理;
如果有Child正在處理事件忿墅,此時如果ViewGroup攔截了當(dāng)前的事件,則要將ViewGroup標(biāo)志位正在處理事件即mFirstTouchTarget設(shè)置為空沮峡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疚脐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子邢疙,更是在濱河造成了極大的恐慌棍弄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疟游,死亡現(xiàn)場離奇詭異呼畸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颁虐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蛮原,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人另绩,你說我怎么就攤上這事儒陨。” “怎么了笋籽?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵蹦漠,是天一觀的道長。 經(jīng)常有香客問我车海,道長笛园,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任容劳,我火速辦了婚禮喘沿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘竭贩。我一直安慰自己蚜印,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布留量。 她就那樣靜靜地躺著窄赋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪楼熄。 梳的紋絲不亂的頭發(fā)上忆绰,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音可岂,去河邊找鬼错敢。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的稚茅。 我是一名探鬼主播纸淮,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼亚享!你這毒婦竟也來了咽块?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤欺税,失蹤者是張志新(化名)和其女友劉穎侈沪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晚凿,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡亭罪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了歼秽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皆撩。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哲银,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呻惕,我是刑警寧澤荆责,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站亚脆,受9級特大地震影響做院,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜濒持,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一键耕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柑营,春花似錦屈雄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奶赔,卻和暖如春惋嚎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背站刑。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工另伍, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绞旅。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓摆尝,卻偏偏與公主長得像温艇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子结榄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容