Android的事件傳遞機(jī)制

事件分發(fā)過(guò)程由下列三個(gè)方法共同完成:

  • boolean dispatchTouchEvent (MotionEvent event)
    用來(lái)進(jìn)行事件的分發(fā)官卡。如果事件可以傳遞給當(dāng)前View夯辖,那么此方法一定會(huì)被調(diào)用温赔。返回結(jié)果受當(dāng)前View的onTouchEvent和子View的dispatchTouchEvent返回結(jié)果的影響晒夹,表示是否消耗當(dāng)前事件嗤练。
  • boolean onInterceptTouchEvent (MotionEvent event)
    在上述方法內(nèi)部調(diào)用楼誓,用來(lái)判斷是否攔截某個(gè)事件。如果當(dāng)前View攔截了某個(gè)事件沪伙,那么在同一個(gè)事件序列過(guò)程中瓮顽,該方法不會(huì)被再次被調(diào)用。返回結(jié)果表示是否攔截當(dāng)前事件围橡。
  • boolean onTouchEvent (MotionEvent event)
    在dispatchTouchEvent方法中調(diào)用暖混,用來(lái)處理當(dāng)前事件。其中翁授,MotionEvent.ACTION_UP時(shí)會(huì)調(diào)用performClick方法儒恋,即mOnClickListener.onClick(this)方法善绎。返回結(jié)果表示是否消耗當(dāng)前事件黔漂,如果不消耗诫尽,則在同一個(gè)事件序列過(guò)程中,當(dāng)前View無(wú)法再次接收到事件炬守。

偽代碼表示事件傳遞規(guī)則:

ViewGroup的分發(fā)過(guò)程
public boolean dispatchTouchEvent(MotionEvent event) {
    boolean consume = false;
    if (onInterceptTouchEvent(event)) {
        consume = super.dispatchTouchEvent(event);
    } else {
        consume = child.dispatchTouchEvent(event);
        if (!consume) {
            consume = super.dispatchTouchEvent(event);
        }
    }
    return consume;
}
View的分發(fā)過(guò)程
public boolean dispatchTouchEvent(MotionEvent event) {
    boolean consume = false;
    if (mOnTouchListener.onTouch(this, event)) {
        consume = true;
    } else {
        consume = onTouchEvent(event);
    }
    return consume;
}

demo效果


默認(rèn)情況.png
父容器攔截事件.png
子View onTouchEvent返回false.png

結(jié)論:

  • 事件處理優(yōu)先級(jí)比較:OnTouchListener.onTouch > onTouchEvent > OnClickListener.onClick牧嫉。
  • 同一個(gè)事件序列是指從手指觸摸屏幕的那一刻起,到手指離開(kāi)屏幕的那一刻結(jié)束减途,在這個(gè)過(guò)程中所產(chǎn)生的一系列事件酣藻。這個(gè)事件序列:down -- 若干個(gè)move -- up。
  • 事件傳遞流程:Activity -> Window -> View鳍置。
  • 當(dāng)一個(gè)View攔截一個(gè)事件后辽剧,那么這個(gè)事件序列都只能由它來(lái)處理,并且它的onInterceptTouchEvent方法不會(huì)再被調(diào)用税产。
  • 正常情況下怕轿,一個(gè)事件序列只能被一個(gè)View攔截且消耗(特殊情況:View通過(guò)onTouchEvent將需要自己處理的事件強(qiáng)行傳遞給其他View)。
  • 某個(gè)View一旦開(kāi)始處理事件辟拷,如果它不消耗ACTION_DOWN事件(onTouchEvent返回false)撞羽,那么同一事件序列中的其他事件都不會(huì)交給它來(lái)處理,而是重新交給它的父元素處理衫冻。
  • 如果View不消耗ACTION_DOWN以外的其他事件诀紊,那么點(diǎn)擊事件會(huì)消失,此時(shí)父元素的onTouchEvent并不會(huì)被調(diào)用隅俘,并且當(dāng)前View可以持續(xù)收到后續(xù)事件邻奠,最終這些點(diǎn)擊事件交給Activity處理。
  • ViewGroup默認(rèn)不攔截任何事件为居。
  • View沒(méi)有onInterceptTouchEvent方法碌宴。
  • View的onTouchEvent默認(rèn)都會(huì)消耗事件(返回true),除非它是不可點(diǎn)擊的颜骤。

應(yīng)用:滑動(dòng)沖突的解決

  • 外部攔截法:重寫(xiě)父容器的onInterceptTouchEvent方法唧喉,判斷是否需要攔截
  • 內(nèi)部攔截法:重寫(xiě)子View的dispatchTouchEvent方法,判斷是否消耗掉事件
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末忍抽,一起剝皮案震驚了整個(gè)濱河市八孝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸠项,老刑警劉巖干跛,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異祟绊,居然都是意外死亡楼入,警方通過(guò)查閱死者的電腦和手機(jī)哥捕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)嘉熊,“玉大人遥赚,你說(shuō)我怎么就攤上這事〔簦” “怎么了凫佛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)孕惜。 經(jīng)常有香客問(wèn)我愧薛,道長(zhǎng),這世上最難降的妖魔是什么衫画? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任毫炉,我火速辦了婚禮,結(jié)果婚禮上削罩,老公的妹妹穿的比我還像新娘瞄勾。我一直安慰自己,他們只是感情好鲸郊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布丰榴。 她就那樣靜靜地躺著,像睡著了一般秆撮。 火紅的嫁衣襯著肌膚如雪四濒。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天职辨,我揣著相機(jī)與錄音盗蟆,去河邊找鬼。 笑死舒裤,一個(gè)胖子當(dāng)著我的面吹牛喳资,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播腾供,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼仆邓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伴鳖?” 一聲冷哼從身側(cè)響起节值,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎榜聂,沒(méi)想到半個(gè)月后搞疗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡须肆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年匿乃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了桩皿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幢炸,死狀恐怖泄隔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阳懂,我是刑警寧澤梅尤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站岩调,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赡盘。R本人自食惡果不足惜号枕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陨享。 院中可真熱鬧葱淳,春花似錦、人聲如沸抛姑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)定硝。三九已至皿桑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蔬啡,已是汗流浹背诲侮。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留箱蟆,地道東北人沟绪。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像空猜,于是被迫代替她去往敵國(guó)和親绽慈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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