Android Event事件傳遞機(jī)制總結(jié)

概述

相信很多寫過復(fù)雜自定義view的人都或多或少遇到一些事件響應(yīng)不對的坑始赎,在這里通過例子具象地把Android里事件分發(fā)消費(fèi)的機(jī)制解析清楚移必,一起來看吧移剪。

事件相關(guān)的主角

涉及到事件分發(fā)的類有Activity篙挽、ViewGroup赶掖、View

涉及到的函數(shù)有dispatchTouchEvent忿危、onInterceptTouchEvent达箍、onTouchEvent

Activity只有dispatchTouchEvent和onTouchEvent,沒有onInterceptTouchEvent

ViewGroup三個函數(shù)都有

View和Activity一樣沒有onInterceptTouchEvent

綜上所述铺厨,Activity和View都沒有onInterceptTouchEvent去攔截事件缎玫。

具體說明及測試?yán)?/h2>

先說說dispatchTouchEvent,當(dāng)事件產(chǎn)生時解滓,首先會進(jìn)入dispatch函數(shù)碘梢,由它決定事件是否繼續(xù)傳遞,它有三種返回值:

  1. true; 返回true表示事件只分發(fā)到這伐蒂,事件由本函數(shù)消費(fèi)煞躬。注意:事件不會分發(fā)到onTouchEvent中
  2. false; 返回false表示事件不往下分發(fā),也不消費(fèi),事件會逐層返回給父View進(jìn)行消費(fèi)
  3. super.dispatchTouchEvent; 系統(tǒng)默認(rèn)處理恩沛,如果有子view就分發(fā)給自己的子view在扰,如果自己是最小顆粒的view了,就直接調(diào)用onTouchEvent消費(fèi)

再來說說onInterceptTouchEvent雷客,如字面意思芒珠,就是攔截事件用的,也有三種返回值:

  1. true; 表示要攔截事件搅裙,事件由當(dāng)前view或viewgroup的onTouchEvent處理
  2. false; 表示不攔截事件皱卓,繼續(xù)往下分發(fā)
  3. super.onInterceptTouchEvent; 系統(tǒng)默認(rèn)處理,不攔截往下分發(fā)

最后說說onTouchEvent部逮,是消費(fèi)事件用的

  1. true; 消費(fèi)事件娜汁,事件結(jié)束
  2. false; 不消費(fèi),事件逐層返回給父View的onTouchEvent進(jìn)行消費(fèi)
  3. super.onTouchEvent; 系統(tǒng)默認(rèn)處理兄朋,同false

這樣說可能只知道方法的用處掐禁,具體傳遞還不明確,有點(diǎn)干颅和,現(xiàn)舉個例子說明吧:

name dispatchTouchEvent onInterceptTouchEvent onTouchEvent
Activity super -- super
ViewGroup super super super
View super -- super

這是最常見的情況傅事,來看下點(diǎn)擊后事件傳遞的結(jié)果:

  1. Activity: dispatchTouchEvent---ACTION_DOWN
  2. ViewGroup: dispatchTouchEvent---ACTION_DOWN
  3. ViewGroup: onInterceptTouchEvent---ACTION_DOWN
  4. View: dispatchTouchEvent---ACTION_DOWN
  5. View: onTouchEvent---ACTION_DOWN
  6. ViewGroup: onTouchEvent---ACTION_DOWN
  7. Activity: onTouchEvent---ACTION_DOWN
  8. Activity: dispatchTouchEvent---ACTION_MOVE
  9. Activity: onTouchEvent---ACTION_MOVE
  10. Activity: dispatchTouchEvent---ACTION_UP
  11. Activity: onTouchEvent---ACTION_UP

因?yàn)閐ispatchTouchEvent全部是系統(tǒng)默認(rèn)處理,往下分發(fā)峡扩,得知路徑是自上而下蹭越,從根布局到子布局一層層傳遞,當(dāng)返回super時教届,如果有onInterceptTouchEvent方法(ViewGroup有)般又,就會先看下是否需要攔截事件,這里super,不攔截巍佑,分發(fā)給View茴迁,因?yàn)閂iew是最小顆粒度的控件了,沒有子view萤衰,所以直接觸發(fā)view的onTouchEvent去消費(fèi)堕义,這里返回super不消費(fèi),則依次返回給viewGroup的onTouchEvent消費(fèi)脆栋,這里viewGroup也不消費(fèi)倦卖,就返回給activity消費(fèi)。

這里看到當(dāng)找不到事件消費(fèi)者時椿争,后續(xù)事件的MOVE和UP都直接交給activity處理了怕膛,不會再分發(fā)∏刈伲可以理解成DOWN事件的分發(fā)就是為了尋找事件消費(fèi)者褐捻,找到了掸茅,后續(xù)的事件就直接交由消費(fèi)者去處理了。

name dispatchTouchEvent onInterceptTouchEvent onTouchEvent
Activity super -- super
ViewGroup true super super
View super -- super

看結(jié)果:

  1. Activity: dispatchTouchEvent---ACTION_DOWN
  2. ViewGroup: dispatchTouchEvent---ACTION_DOWN
  3. Activity: dispatchTouchEvent---ACTION_MOVE
  4. ViewGroup: dispatchTouchEvent---ACTION_MOVE
  5. Activity: dispatchTouchEvent---ACTION_UP
  6. ViewGroup: dispatchTouchEvent---ACTION_UP

從結(jié)果可以發(fā)現(xiàn)柠逞,dispatchTouchEvent返回true時昧狮,直接消費(fèi)事件了,也不會經(jīng)過onInterceptTouchEvent和onTouchEvent板壮。

name dispatchTouchEvent onInterceptTouchEvent onTouchEvent
Activity super -- super
ViewGroup false super super
View super -- super

看結(jié)果:

  1. Activity: dispatchTouchEvent---ACTION_DOWN
  2. ViewGroup: dispatchTouchEvent---ACTION_DOWN
  3. Activity: onTouchEvent---ACTION_DOWN
  4. Activity: dispatchTouchEvent---ACTION_MOVE
  5. Activity: onTouchEvent---ACTION_MOVE
  6. Activity: dispatchTouchEvent---ACTION_UP
  7. Activity: onTouchEvent---ACTION_UP

從結(jié)果可以發(fā)現(xiàn)逗鸣,dispatchTouchEvent返回false時,不往下分發(fā)事件绰精,事件直接返回上層去處理了撒璧,就到了Activity的onTouchEvent處理

name dispatchTouchEvent onInterceptTouchEvent onTouchEvent
Activity super -- super
ViewGroup super true super
View super -- super

看結(jié)果:

  1. Activity: dispatchTouchEvent---ACTION_DOWN
  2. ViewGroup: dispatchTouchEvent---ACTION_DOWN
  3. ViewGroup: onInterceptTouchEvent---ACTION_DOWN
  4. ViewGroup: onTouchEvent---ACTION_DOWN
  5. Activity: onTouchEvent---ACTION_DOWN
  6. Activity: dispatchTouchEvent---ACTION_MOVE
  7. Activity: onTouchEvent---ACTION_MOVE
  8. Activity: dispatchTouchEvent---ACTION_UP
  9. Activity: onTouchEvent---ACTION_UP

從結(jié)果可以發(fā)現(xiàn),onInterceptTouchEvent返回true笨使,攔截了事件卿樱,把事件由攔截事件的ViewGroup進(jìn)行處理,所以走到了viewGroup的onTouchEvent阱表,因?yàn)関iewGroup沒有消費(fèi)事件殿如,所以事件直接返回上層去處理了贡珊,就到了Activity的onTouchEvent處理

name dispatchTouchEvent onInterceptTouchEvent onTouchEvent
Activity super -- super
ViewGroup super true true
View super -- super

看結(jié)果:

  1. Activity: dispatchTouchEvent---ACTION_DOWN
  2. ViewGroup: dispatchTouchEvent---ACTION_DOWN
  3. ViewGroup: onInterceptTouchEvent---ACTION_DOWN
  4. ViewGroup: onTouchEvent---ACTION_DOWN
  5. Activity: dispatchTouchEvent---ACTION_MOVE
  6. ViewGroup: dispatchTouchEvent---ACTION_MOVE
  7. ViewGroup: onTouchEvent---ACTION_MOVE
  8. Activity: dispatchTouchEvent---ACTION_UP
  9. ViewGroup: dispatchTouchEvent---ACTION_MOVE
  10. ViewGroup: onTouchEvent---ACTION_UP

從結(jié)果可以發(fā)現(xiàn)最爬,ViewGroup的onTouchEvent返回true,消費(fèi)了事件后门岔,系統(tǒng)找到了可以消費(fèi)事件的view爱致,所以后續(xù)的MOVE\UP事件全部都分發(fā)到viewGroup里去消費(fèi)了

總結(jié)

由以上例子可以得出結(jié)論,DOWN事件的分發(fā)是為了找到可以消費(fèi)事件的目標(biāo)view寒随,找到后就會把后面的事件直接分發(fā)到此目標(biāo)view中糠悯。

分發(fā)是自上而下的,從根布局一直分發(fā)到子布局妻往,而消費(fèi)是自下而上的互艾,子view不消費(fèi)就會傳遞給父view去消費(fèi),只要有地方消費(fèi)了事件就中止傳遞讯泣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纫普,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子好渠,更是在濱河造成了極大的恐慌昨稼,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拳锚,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)趴久,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門悯周,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拌蜘,“玉大人,你說我怎么就攤上這事棋凳±棺梗” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵剩岳,是天一觀的道長贞滨。 經(jīng)常有香客問我,道長拍棕,這世上最難降的妖魔是什么晓铆? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮绰播,結(jié)果婚禮上骄噪,老公的妹妹穿的比我還像新娘。我一直安慰自己蠢箩,他們只是感情好链蕊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谬泌,像睡著了一般滔韵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上掌实,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天陪蜻,我揣著相機(jī)與錄音,去河邊找鬼贱鼻。 笑死宴卖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邻悬。 我是一名探鬼主播症昏,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼父丰!你這毒婦竟也來了肝谭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤础米,失蹤者是張志新(化名)和其女友劉穎分苇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屁桑,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡医寿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蘑斧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片靖秩。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡须眷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沟突,到底是詐尸還是另有隱情花颗,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布惠拭,位于F島的核電站扩劝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏职辅。R本人自食惡果不足惜棒呛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望域携。 院中可真熱鬧簇秒,春花似錦、人聲如沸秀鞭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锋边。三九已至皱坛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宠默,已是汗流浹背麸恍。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工灵巧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搀矫,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓刻肄,卻偏偏與公主長得像瓤球,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子敏弃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

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