版權(quán)聲明:本文來自門心叼龍的博客,屬于原創(chuàng)內(nèi)容,轉(zhuǎn)載請(qǐng)注明出處:https://blog.csdn.net/geduo_83/article/details/90145083
github源碼下載地址:https://github.com/geduo83/android-touch-event
Android事件分發(fā)機(jī)制的探索與發(fā)現(xiàn)之View篇
Android事件分發(fā)機(jī)制的探索與發(fā)現(xiàn)之ViewGroup篇
Android事件分發(fā)機(jī)制的探索與發(fā)現(xiàn)之Activity篇
Android事件分發(fā)機(jī)制的探索與發(fā)現(xiàn)之總結(jié)篇
Android事件分發(fā)機(jī)制在實(shí)戰(zhàn)開發(fā)中的應(yīng)用之一
Android事件分發(fā)機(jī)制在實(shí)戰(zhàn)開發(fā)中的應(yīng)用之二
在這之前我在網(wǎng)上看到一篇文章也是關(guān)于andoid的事件分發(fā)機(jī)制,我覺得他的總結(jié)比喻很到位做院,他說事件分發(fā)好比是領(lǐng)導(dǎo)給下屬派活萨西,假如有一個(gè)小公司,就三個(gè)級(jí)別吊奢,老板,經(jīng)理,員工页滚,老板現(xiàn)在有一個(gè)任務(wù)召边,他首先會(huì)把這是任務(wù)派給經(jīng)理,然后經(jīng)理接到這個(gè)任務(wù)裹驰,會(huì)把這個(gè)任務(wù)交給下面的員工去完成隧熙,如果這個(gè)員工覺得這個(gè)任務(wù)能搞定,那么他就把這個(gè)任務(wù)完成了幻林,如果搞不定他會(huì)告訴他們的經(jīng)理贞盯,經(jīng)理拿到這個(gè)任務(wù)之后,如果經(jīng)理能搞定沪饺,經(jīng)理就自己完成了躏敢,如果他也搞不定,他就會(huì)去找老板整葡,最終老板自己把這個(gè)任務(wù)給完成了件余。這個(gè)過程是不是和我們的View事件分發(fā)很像,我太佩服我這位網(wǎng)友了遭居,簡直是太形象了蛾扇,但我更佩服谷歌的這些大神們,他們把事件傳遞機(jī)制設(shè)計(jì)的竟如此精妙魏滚。
好了镀首,現(xiàn)在我們言歸正傳,截止目前關(guān)于View事件傳遞機(jī)制的View篇鼠次,ViewGroup篇更哄,Activity篇就已經(jīng)全部講完了,在前面幾篇文章,我們主要通過不斷的修改View,ViewGroup,以及Activity他們的dispatchTouchEvent方法,onInterceptTouchevent方法和onTouchevent方法的返回值來測試整個(gè)android系統(tǒng)的事件分發(fā)流程腥寇,為此我畫了一張泳道流程圖幫助大家來理解它成翩,這張圖比網(wǎng)上大部分流程圖好理解多了,因?yàn)槲铱淳W(wǎng)上很多觸摸事件流程圖都是View和ViewGroup是分開畫的赦役,這樣一來就把一個(gè)完整的事物分割開來麻敌,直接就導(dǎo)致很多人當(dāng)時(shí)是記住了,過一陣一就忘記了掂摔,要么就是記混淆了术羔,有了這張圖流程圖,媽媽再也不用擔(dān)心我們?cè)趶?fù)雜的事件分發(fā)中迷路了乙漓。
Activity的事件分發(fā)機(jī)制
如果事件在傳遞過程中级历,對(duì)事件分發(fā)函數(shù),如果調(diào)用父類的同名方法則事件繼續(xù)往下級(jí)View進(jìn)行分發(fā)叭披,如果進(jìn)行了人工干預(yù)寥殖,返回true或者false則表示消費(fèi)掉了,無論dispathTouchEvent返回什么值A(chǔ)ctivity的onTouchEvent方法永遠(yuǎn)不會(huì)被調(diào)用的,除非它下級(jí)子View的dispathTouchEvent方法或者onTouchEvent方法返回false嚼贡,觸摸事件才能回傳給我們的Activity的onTouchEvent方法熏纯,才能引起Activity的onTouchEvent方法的調(diào)用
ViewGroup的事件傳遞機(jī)制
觸摸事件的傳遞順序是由Activity到ViewGroup,再由ViewGroup遞歸傳遞給他的子View
如果事件在傳遞過程中粤策,對(duì)事件分發(fā)函數(shù)進(jìn)行了人工干預(yù)樟澜,返回true表示事件被自行消費(fèi),返回false則回傳給父View的onTouchEvent進(jìn)行處理掐场,此時(shí)后面的事件都接受不到了往扔,調(diào)用同名方法則繼續(xù)交給他的onInterceptTouchEvent方法進(jìn)行處理
onInterceptTouchEvent方法對(duì)事件進(jìn)行攔截贩猎,如果該方法返回true熊户,則事件不會(huì)繼續(xù)往下傳遞給子View,而是交給自己的onTouchEvent進(jìn)行處理吭服,如果返回false或者是調(diào)用父類的同名方法則表示事件會(huì)繼續(xù)會(huì)傳遞給子View
如果事件在傳遞過程中嚷堡,對(duì)事件處理函數(shù)進(jìn)行了人工干預(yù),返回true則表示該事件被消費(fèi)艇棕,返回false和調(diào)用同名方法則表示該事件回傳給父類的同名方法進(jìn)行處理
View的事件傳遞機(jī)制
觸摸事件的傳遞流程是從dispatchTouchEvent開始的蝌戒,如果不進(jìn)行人工干預(yù),則事件將會(huì)依照View樹的嵌套層次從外層向內(nèi)層傳遞沼琉,到達(dá)最內(nèi)層的View時(shí)北苟,就由它的onTouchVent方法處理
如果事件在傳遞過程中,對(duì)事件分發(fā)函數(shù)進(jìn)行了人工干預(yù)打瘪,如果返回true表示自行消費(fèi)友鼻,返回父類的同名方法則該事件傳遞給自身的onTouchEvent進(jìn)行處理,返回false表示該事件會(huì)回傳給父view的onTouchEvent方法進(jìn)行處理闺骚,此時(shí)后面的事件都接受不到了彩扔,最后由哪個(gè)View處理,以后的所有事件都交由它來處理
如果事件在傳遞過程中僻爽,對(duì)事件處理函數(shù)進(jìn)行了人工干預(yù)虫碉,返回true和調(diào)用同名方法表示該事件被消費(fèi),返回false則表示該事件回傳給父View的onTouchEvent進(jìn)行處理
事件觸發(fā)是先觸發(fā)onTouch胸梆,再觸發(fā)onClick敦捧,如果onTouch方法返回tue,表示消費(fèi)掉該事件碰镜,不在繼續(xù)進(jìn)行事件傳遞绞惦,onClick也不會(huì)被調(diào)用,如果onTouch方法返回false洋措,則繼續(xù)會(huì)事件傳遞济蝉,onClick會(huì)被調(diào)用
事件傳遞的三個(gè)階段
-
按照View進(jìn)行劃分
按照View進(jìn)行劃分 -
按照事件進(jìn)行劃分
按照事件進(jìn)行劃分
結(jié)論:無論是View還是ViewGroup ,調(diào)用dispatchTouchEvent方法的時(shí)候,返回true表示自行消費(fèi)了王滤,返回false表示事件會(huì)回傳給父View的onTouchEvent方法進(jìn)行處理贺嫂,只有調(diào)用父類同名方法的時(shí)候略有不同,如果是ViewGroup表示該事件會(huì)分發(fā)給他的onInterceptTouchEvent方法進(jìn)行處理雁乡,如果是View則表示還事件會(huì)分發(fā)給自己的onTouchEvent方法進(jìn)行處理第喳。
無論是View還是ViewGroup ,如果是調(diào)用了onTouchEvent方法踱稍,方法返回true表示消費(fèi)掉了曲饱,返回false表示該事件會(huì)回傳給父View的onTouchEvent方法進(jìn)行處理的,只是調(diào)用父類的同名方法的時(shí)候處理的邏輯略有不同珠月,如果是View則表示該事件被消費(fèi)掉了扩淀,如果是ViewGourp也表示該事件會(huì)回傳給父View的onTouchEvent方法進(jìn)行處理,View偏重消費(fèi)啤挎、ViewGourp偏重分發(fā)驻谆。
無論是View,還是ViewGourp庆聘,無論是調(diào)用dispatchTouchEvent方法胜臊,還是調(diào)用了onTouchEvent,返回true表示消費(fèi)掉了伙判,返回false表示事件回傳給父View了象对,只是調(diào)用父類的同名方法的時(shí)候略有不同。