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

參考:http://blog.csdn.net/yanbober/article/details/45887547

工程git地址

http://git.oschina.net/blnm/anzhuoviewchumochuandi

花了3天研究了上面的博客 主要是View篇, 總結(jié)出一些比較簡(jiǎn)單易懂 結(jié)論.我猜很多人像我一樣也是不愿意看源碼的,只是想知道怎么用而已,使用對(duì)象,而不需要了解對(duì)象實(shí)現(xiàn)功能的原理.

網(wǎng)上有些博客說(shuō)的是錯(cuò)的,本文經(jīng)過(guò)我代碼測(cè)試,基本毛病不大.




View 觸摸相關(guān)的方法有很多比如下面的

可以寫(xiě)在activity里的方法:

setOnClickListener

setOnTouchListener

寫(xiě)在自定義view里的方法

dispatchTouchEvent (返回值表示接收到手勢(shì)事件) A

onTouchEvent (返回值表示接收到手勢(shì)事件) ?B

B影響A


event是觸摸對(duì)象 ?event里面有個(gè)action屬性 ?

Action 有3個(gè)狀態(tài) 和對(duì)應(yīng)的int值 :?

down--0

?move--2

?up--1


基本順序:

dispatchTouchEvent ->onTouchListener ->onTouchEvent(前3個(gè)是循環(huán) 因?yàn)閍ction 有3種狀態(tài) 所以會(huì)循環(huán)3次 第三次up執(zhí)行下面的) ->setOnClickListener

在View的觸摸屏傳遞機(jī)制中通過(guò)分析dispatchTouchEvent方法源碼我們會(huì)得出如下基本結(jié)論:

觸摸控件(View)首先執(zhí)行dispatchTouchEvent方法墩新。

dispatchTouchEvent返回值與View里的該方法做了什么

先調(diào)用View里的方法,第一次接收到action (一般是down狀態(tài)), 執(zhí)行__________A邏輯__________,如果設(shè)置了ontouchListern 或者 onTouchEvent都會(huì)返回true

返回true 就會(huì)繼續(xù)接受touch的 后續(xù)動(dòng)作 如:move? UP? 如果返回false? 接收不到后面的 動(dòng)作 (或者說(shuō)是狀態(tài))了



下面是A,B 2個(gè)邏輯是根據(jù)源碼得出的結(jié)論

__________A邏輯____start______:如果設(shè)置了onTouchListener事件

返回值為true ?那么 dispatchTouchEvent ?返回 ture onTouchEvent不執(zhí)行

如果沒(méi)有設(shè)置onTouchListener事件 或者設(shè)置返回值為false? 則會(huì)調(diào)用onTouchEvent(event)

onTouchEvent 返回值參照___邏輯B____.

onTouchEvent的返回值會(huì)影響下次dispath的返回值 (如果true 該View接收事件 如果是false就是接收不到action下面的狀態(tài))


onClickListerner就在onTouchEvent中被調(diào) 執(zhí)行的,而且是在onTouchEvent的ACTION_UP事件中執(zhí)行的窟坐。


/____A邏輯____end___



__________B邏輯______start____

onTouchEcent默認(rèn)是返回false

如設(shè)置view.setClickable 或者設(shè)置onClickListerner:達(dá)到onTouchEcent返回true

v.setEnabled(false);(enable如果false ?onTouchListerner 和onClickListerner2個(gè)方法不執(zhí)行)

v.setClickable(true);

onTouchEvent直接消費(fèi)事件返回true

v.setEnabled(false);

v.setClickable(false);

onTouchEvent返回false


v.setEnabled(true);

v.setClickable(false);

onTouchEvent返回false

v.setEnabled(true);

v.setClickable(true);

onTouchEvent返回true

---------------------------------

View如果沒(méi)寫(xiě)回調(diào)事件 默認(rèn)onTouchEvent返回false

如果只寫(xiě)了onClickonTouchEvent返回true

如果寫(xiě)了onTouchListerner? (這個(gè)方法返回false onTouchEvent返回true 這個(gè)方法返回true? onTouchEvent不執(zhí)行)


自動(dòng)以按鈕 繼承系統(tǒng)按鈕 執(zhí)行順序如下

dispatchTouchEvent方法先派發(fā)down事件海渊,完事調(diào)運(yùn)onTouch绵疲,完事調(diào)運(yùn)onTouchEvent返回true,同時(shí)dispatchTouchEvent返回true切省,然后dispatchTouchEvent繼續(xù)派發(fā)move或者up事件最岗,循環(huán)帕胆,直到onTouchEvent處理up事件時(shí)調(diào)運(yùn)onClick事件朝捆,完事返回true,同時(shí)dispatchTouchEvent返回true懒豹;一次完整的View事件派發(fā)流程結(jié)束

/_________B邏輯___end_______















下面是ViewGroup具體總結(jié)如下:

Android事件派發(fā)是先傳遞到最頂級(jí)的ViewGroup芙盘,再由ViewGroup遞歸傳遞到View的。

在ViewGroup中可以通過(guò)onInterceptTouchEvent方法對(duì)事件傳遞進(jìn)行攔截脸秽,onInterceptTouchEvent方法返回true代表不允許事件繼續(xù)向子View傳遞儒老,返回false代表不對(duì)事件進(jìn)行攔截,默認(rèn)返回false记餐。

子View中如果將傳遞的事件消費(fèi)掉驮樊,ViewGroup中將無(wú)法接收到任何事件。

在Activity的觸摸屏事件派發(fā)中:

首先會(huì)觸發(fā)Activity的dispatchTouchEvent方法片酝。

dispatchTouchEvent方法中如果是ACTION_DOWN的情況下會(huì)接著觸發(fā)onUserInteraction方法囚衔。

接著在dispatchTouchEvent方法中會(huì)通過(guò)Activity的root View(id為content的FrameLayout),實(shí)質(zhì)是ViewGroup雕沿,通過(guò)super.dispatchTouchEvent把touchevent派發(fā)給各個(gè)activity的子view练湿,也就是我們?cè)貯ctivity.onCreat方法中setContentView時(shí)設(shè)置的view。

若Activity下面的子view攔截了touchevent事件(返回true)則Activity.onTouchEvent方法就不會(huì)執(zhí)行审轮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肥哎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疾渣,更是在濱河造成了極大的恐慌篡诽,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榴捡,死亡現(xiàn)場(chǎng)離奇詭異杈女,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)薄疚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)碧信,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人街夭,你說(shuō)我怎么就攤上這事砰碴。” “怎么了板丽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵呈枉,是天一觀的道長(zhǎng)趁尼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)猖辫,這世上最難降的妖魔是什么酥泞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮啃憎,結(jié)果婚禮上芝囤,老公的妹妹穿的比我還像新娘。我一直安慰自己辛萍,他們只是感情好悯姊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著贩毕,像睡著了一般悯许。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辉阶,一...
    開(kāi)封第一講書(shū)人閱讀 49,856評(píng)論 1 290
  • 那天先壕,我揣著相機(jī)與錄音,去河邊找鬼谆甜。 笑死垃僚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的店印。 我是一名探鬼主播冈在,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼按摘!你這毒婦竟也來(lái)了包券?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤炫贤,失蹤者是張志新(化名)和其女友劉穎溅固,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體兰珍,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侍郭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掠河。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亮元。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖唠摹,靈堂內(nèi)的尸體忽然破棺而出爆捞,到底是詐尸還是另有隱情,我是刑警寧澤勾拉,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布煮甥,位于F島的核電站盗温,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏成肘。R本人自食惡果不足惜卖局,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望双霍。 院中可真熱鬧砚偶,春花似錦、人聲如沸店煞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顷蟀。三九已至,卻和暖如春骡技,著一層夾襖步出監(jiān)牢的瞬間鸣个,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工布朦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囤萤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓是趴,卻偏偏與公主長(zhǎng)得像涛舍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唆途,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

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