Android事件攔截機(jī)制

事件攔截

主要是View的onInterceptTouchEvent()方法對touch事件進(jìn)行攔截琅捏。
onInterceptTouchEvent:Touch事件攔截方法

圖示:

從外到里的View包含關(guān)系依次為:A->B->C->D

(1)onInterceptTouchEvent()方法對touch事件進(jìn)行攔截,對于嵌套的View吠冤,最先執(zhí)行的是最外層View的onInterceptTouchEvent()方法答朋。然后依次執(zhí)行子視圖的onInterceptTouchEvent()方法,子視圖的子視圖的onInterceptTouchEvent()方法。(這里假設(shè)所有嵌套視圖的onInterceptTouchEvent都會得到執(zhí)行卿樱,即每一個View的onInterceptTouchEvent方法返回都為false的情況)

參照上圖,事件攔截順序:onInterceptTouchEvent執(zhí)行順序依次為:A->B->C->D硫椰,也就是父視圖向子視圖傳遞繁调。

總之,事件攔截機(jī)制是由父視圖開始發(fā)起對事件的攔截(出事了老子先上靶草,兒子稍后)蹄胰。參照上圖當(dāng)手指觸摸事件時(shí),父視圖A首先發(fā)起對該起事件的攔截奕翔,如果A攔截失敗裕寨,就交給它的子視圖B進(jìn)行攔截;如果B攔截失敗就交給B的子視圖C再進(jìn)行攔截..直到某一子視圖對該次事件攔截成功派继。

(2)某一視圖攔截事件成功與否的判斷標(biāo)識是onInterceptTouchEvent方法的返回值宾袜,當(dāng)返回true的時(shí)候說明攔截成功,返回false的時(shí)候說明當(dāng)前視圖對事件攔截失敗驾窟。

也就是說庆猫,只有當(dāng)父視圖的onInterceptTouchEvent返回為false時(shí),事件才向子視圖onInterceptTouchEvent傳遞绅络。返回為true時(shí)月培,表示事件攔截成功,不再向下傳遞恩急,事件交由該View的onTouchEvent方法來處理节视。子視圖的onInterceptTouchEvent不會執(zhí)行。

(3)攔截成功情況

視圖C對當(dāng)前的touch事件攔截成功:此時(shí)意味著C的onInterceptTouchEvent方法返回true假栓,事件將不再向D進(jìn)行傳遞寻行。事件攔截成功后,緊接著需要對攔截的事件進(jìn)行處理匾荆,由視圖C的onTouchEvent方法來執(zhí)行拌蜘。這是不是就意味著當(dāng)前touch事件是由C視圖的onTouchEvent方法來處理的呢?

這要由C視圖的onTouchEvent方法的返回值來決定牙丽。當(dāng)C視圖的onTouchEvent返回true的時(shí)候简卧,當(dāng)前事件就由C全權(quán)處理。

處理的當(dāng)然是事件的各種action烤芦,什么MotionEvent.ACTION_MOVE,ACTION_UP都交給了C的onTouchEvent方法進(jìn)行處理举娩。所以此時(shí)就可以在C的onTouchEvent方法中進(jìn)行switch(event.getAction)判斷執(zhí)行相關(guān)邏輯了。

如果返回的false,說明C視圖對此事件不做處理或者處理不了,怎么辦呢铜涉?兒子不行老爸來智玻,于是事件就交到了B視圖的onTouchEvent方法中。同樣B對此事件處理與否還是看B的onTouchEvent返回值芙代,具體的解釋就跟C一樣了吊奢,不復(fù)多言。

(4)攔截失敗情況

如上圖纹烹,在A B C D的onInterceptTouchEvent和onTouchEvent都返回false的情況下页滚,方法執(zhí)行的順序依次為A.onInterceptTouchEvent-->B.onInterceptTouchEvent-->C.onInterceptTouchEvent-->D.touchEvent(最深的子視圖沒重寫onInterceptTouchEvent)-->C.touchEvent-->B.touchEvent-->A.touchEvent.

也就是說攔截事件是父視圖優(yōu)先有子視圖進(jìn)行攔截,處理事件是子視圖優(yōu)先父視圖進(jìn)行處理铺呵。

總結(jié):onInterceptTouchEvent負(fù)責(zé)對事件進(jìn)行攔截裹驰,攔截成功后交給最先遇到onTouchEvent返回true的那個view進(jìn)行處理。


圖解:

一片挂、onInterceptTouchEvent方法返回值情況(此時(shí)默認(rèn)每個onTouchEvent都返回false)

(1)所有ABCD視圖都對該事件不攔截和不處理的情況邦马,當(dāng)傳遞到最末端的子視圖D時(shí)對touch事件進(jìn)行處理,之后事件處理向父視圖傳遞宴卖。(默認(rèn)葉子View是沒有onInterceptTouchEvent方法的滋将,只有onTouchEvent事件進(jìn)行事件處理),也就是所有的onIntercetpTouchEvent方法和onTouchEvent方法都返回false值症昏。
(2)A視圖的onInterceptTouchEvent方法對事件進(jìn)行了攔截随闽,即返回true,則:事件不再向子視圖傳遞肝谭,此時(shí)由A的onTouchEvent方法進(jìn)行事件處理掘宪。
(3)只有B的onInterceptTouchEvent方法對事件進(jìn)行了攔截,即返回true攘烛,則:事件不再向子視圖傳遞魏滚,此時(shí)由B的onTouchEvent方法進(jìn)行事件處理。若此時(shí)B視圖的onTouchEvent方法返回false坟漱,則事件向B的父視圖A傳遞鼠次。
(4)同理,只有C的onInterceptTouchEvent方法對事件進(jìn)行了攔截芋齿,即返回true腥寇,則:事件不再向子視圖傳遞,此時(shí)由C的onTouchEvent方法進(jìn)行事件處理觅捆。若此時(shí)C視圖的onTouchEvent方法返回false赦役,則事件向C的父視圖B傳遞。

二栅炒、onTouchEvent方法返回值情況(此時(shí)默認(rèn)每個onInterceptTouchEvent都返回false掂摔,對事件不攔截)

(1)當(dāng)D的onTouchEvent方法返回true术羔,則表明D對該touch事件全權(quán)處理,事件不再向父視圖傳遞乙漓。
img
(2)當(dāng)C的onTouchEvent方法返回true级历,則表明D處理不了該事件,交由C對該touch事件全權(quán)處理簇秒,事件不再向父視圖B傳遞。
img

三秀鞭、dispatchTouchEvent的返回值情況(該方法只有Activity和ViewGroup含有趋观,View不含)

dispatchTouchEvent顧名思義,事件分發(fā)

一般事件分發(fā)锋边,都是從Activity的DispatchTouchEvent收到觸摸事件的Action_down的時(shí)候皱坛,再將事件分發(fā)給ViewGroup的DispatchTouchEvent的。(事件都是從ACTION_DOWN開始的豆巨,Activity的dispatchTouchEvent()首先接收到ACTION_DOWN剩辟,執(zhí)行super.dispatchTouchEvent(ev),事件向下分發(fā)往扔。)

dispatchTouchEvent()返回true贩猎,后續(xù)事件(ACTION_MOVE、ACTION_UP)會再傳遞萍膛,如果返回false吭服,dispatchTouchEvent()就接收不到ACTION_UP、ACTION_MOVE蝗罗。

(1)ACTION_DOWN都沒被消費(fèi)
(2)a艇棕、ACTION_DOWN被View消費(fèi)了
b、后續(xù)ACTION_MOVE和UP在不被攔截的情況下都會去找VIEW
(3)后續(xù)的被攔截了

Touch事件

android中的Touch事件都是從ACTION_DOWN開始的:
單手指操作:ACTION_DOWN -> ACTION_MOVE -> ACTION_UP
多手指操作:ACTION_DOWN -> ACTION_POINTER_DOWN -> ACTION_MOVE -> ACTION_POINTER_UP -> ACTION_UP.

參考文章:
https://blog.csdn.net/chunqiuwei/article/details/41084921
http://www.reibang.com/p/9f521f34386a
https://blog.csdn.net/xyz_lmn/article/details/12517911

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末串塑,一起剝皮案震驚了整個濱河市沼琉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桩匪,老刑警劉巖打瘪,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異傻昙,居然都是意外死亡瑟慈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門屋匕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來葛碧,“玉大人,你說我怎么就攤上這事过吻〗茫” “怎么了蔗衡?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長乳绕。 經(jīng)常有香客問我绞惦,道長,這世上最難降的妖魔是什么洋措? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任济蝉,我火速辦了婚禮,結(jié)果婚禮上菠发,老公的妹妹穿的比我還像新娘王滤。我一直安慰自己,他們只是感情好滓鸠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布雁乡。 她就那樣靜靜地躺著,像睡著了一般糜俗。 火紅的嫁衣襯著肌膚如雪踱稍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天悠抹,我揣著相機(jī)與錄音珠月,去河邊找鬼。 笑死楔敌,一個胖子當(dāng)著我的面吹牛桥温,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梁丘,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼侵浸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了氛谜?” 一聲冷哼從身側(cè)響起掏觉,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎值漫,沒想到半個月后澳腹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杨何,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年酱塔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片危虱。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡羊娃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出埃跷,到底是詐尸還是另有隱情蕊玷,我是刑警寧澤邮利,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站垃帅,受9級特大地震影響延届,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贸诚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一方庭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酱固,春花似錦械念、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽髓窜。三九已至扇苞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寄纵,已是汗流浹背鳖敷。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留程拭,地道東北人定踱。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像恃鞋,于是被迫代替她去往敵國和親崖媚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345