Android——觸摸事件傳遞機制

個人博客:haichenyi.com。感謝關(guān)注

預(yù)知識點

  1. Android的一次點擊事件由三部分組成:
  • ACTION_DOWN(按下):只能有一個
  • ACTION_UP(抬起):只能有一個
  • ACTION_MOVE(移動):一個或者多個

??為什么移動事件能有多個呢砾省?因為你手指按在屏幕上滑動會觸發(fā)多個MOVE事件,而這次點擊事件的結(jié)束鸳劳,是在你手指離開屏幕的那一刻,才結(jié)束也搓。

  1. Android的事件傳遞是責(zé)任鏈的模式赏廓,一層一層的向下傳遞涵紊,傳遞到最下層之后,沒人認(rèn)領(lǐng)幔摸,就一層一層的往回傳(這就是很多人說的從外到內(nèi)摸柄,再從內(nèi)到外)

Android點擊事件

結(jié)論

?? 簡單的分析成從 Activity——ViewGroup——View,結(jié)論:如下圖

不做任何處理的結(jié)論圖.png

有幾點要注意:

  • dispatch分發(fā)方法既忆,不做任何處理驱负,表示向下分發(fā)
  • onIntercept攔截方法,不做任何處理患雇,表示不攔截
  • onTouchEvent跃脊,不做任何處理,表示不處理事件
  • view group比activity和view多一個攔截方法苛吱。activity不需要攔截方法是因為酪术,他要么向下分發(fā),要么自己處理不需要攔截翠储。view也類似绘雁,要么分發(fā),要么回傳援所。

這個圖就是我們不修改默認(rèn)的返回值的情況下咧七,全部都是super的方式一層一層傳遞的結(jié)論。最上層的activity任斋,中間層的viewgroup,最下層的view耻涛。跟著箭頭的方向看:

  1. activity的分發(fā)事件不做處理废酷,分發(fā)給中間層view group去做分發(fā)
  2. view group的分發(fā)事件也不做處理,傳遞給自己的攔截方法
  3. view group的攔截事件不做處理抹缕,傳遞給最下層的view去做分發(fā)
  4. view的分發(fā)事件不做處理澈蟆,它也沒有下一層了,所以卓研,它就會傳遞給自己的onTouchEvent方法趴俘,去處理事件
  5. view的onTouchEvent方法,不做任何處理奏赘,那么寥闪,它就會回傳給中間層view group的onTouchEvent方法
  6. view group的onTouchEvent方法不做處理,就會回傳給最上層activity的onTouchEvent方法
  7. 如果磨淌,最上層的activity的onTouchEvent方法也不做處理疲憋,那么,系統(tǒng)就會拋棄這次點擊事件梁只,也就是 這次點擊事件沒有任何反應(yīng)缚柳。

以上就是一次點擊事件不做處理的正常流程

上面的結(jié)論是怎么的出來的呢埃脏?就是新建一個view group,新建一個view秋忙,重寫這幾個方法矗积,打印日志讨勤,其他啥也沒動。

activity布局圖.png
viewgroup圖.png
view圖.png
activity布局圖.png

想要驗證上面的結(jié)論,自己也可以去寫了試一下百匆,沒有什么難點,就是打印日志非迹,把view寫到activity布局里面惩歉,然后點擊view就行了

埋個點:這里日志打印都在super前面。

那么裁奇,問題來了桐猬,如果:

  1. 某一層不想要分發(fā)這次事件,怎么辦呢刽肠?(dispatch)
  2. view group想要攔截這次事件溃肪,怎么辦?(onIntercept)
  3. 某一層想自己處理音五,不回傳了惫撰,怎么辦?(onTouchEvent)

某一層不想要分發(fā)這次事件躺涝,怎么辦呢厨钻?(dispatch)

??activity層如果想要不分發(fā)這次點擊事件,自己的onTouchEvent直接處理坚嗜。你只有不調(diào)用super方法夯膀,直接寫死返回值,不管是true苍蔬,還是false诱建,都會直接調(diào)用自己的onTouchEvent方法。就像下面這樣:

//activity的dispatchTouchEvent方法
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.v("hcy","activity:dispatchTouchEvent:"+ev.getAction());
        //只要你調(diào)用了super方法碟绑,不管是返回true還是false俺猿,都會正常的向下傳遞
//        super.dispatchTouchEvent(ev);
        return true;
        return false;
    }

運行的結(jié)論我就不貼出來了。最后再總結(jié)一張總圖

??view group不分發(fā)格仲,此時押袍,activity已經(jīng)分發(fā)下來了,view group不想往下分發(fā)了凯肋,就需要回傳回activity的onTouchEvent方法伯病。寫法如下:

//view group的dispatchTouchEvent方法
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.v("hcy","viewGroup:dispatchTouchEvent:"+ev.getAction());
        //不調(diào)用super方法,返回true,流程就會在這里中斷午笛,分發(fā)方法就直接消費了這次事件
//        return super.dispatchTouchEvent(ev);
        return false;
    }

??view 不想分發(fā)惭蟋,就需要回傳給view group的onTouchEvent方法,然后是否需要回傳給activity的onTouchEvent方法药磺,就需要view group的onTouchEvent方法的返回值去判斷了告组,后面再說。

//view 的dispatchTouchEvent方法
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.v("hcy","view:dispatchTouchEvent:"+event.getAction());
//        return super.dispatchTouchEvent(event);
        return false;
    }

那么癌佩,結(jié)論就如下表格:

return true false super.dispatchTouchEvent(event)
activity 中斷 中斷 分發(fā)
view group 中斷 不分發(fā) 分發(fā)
view 中斷 不分發(fā) 分發(fā)

ps:中斷:表示整個流程就中斷了木缝,沒有任何回調(diào)了

不分發(fā):表示正常回調(diào)围辙,符合預(yù)期

符合預(yù)期我碟,需要去思考一下。我們這里是不分發(fā)姚建,就把事件還給上一層矫俺,那么,

  1. view group掸冤,就是觸發(fā)activity的onTouchEvent方法厘托。
  2. view,就是觸發(fā)view group的onTouchEvent方法稿湿。

view group想要攔截這次事件铅匹,怎么辦?(onIntercept)

//view group的攔截事件
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.v("hcy","viewGroup:onInterceptTouchEvent:"+ev.getAction());
//        return super.onInterceptTouchEvent(ev);
        return true;
    }

攔截事件:表示攔截了自己處理

那么饺藤,結(jié)論就如下表格:

return true false super.onInterceptTouchEvent(event)
view group 攔截 不攔截 不攔截

這里的攔截包斑,會觸發(fā)自己的onTouchEvent方法。

上面的不分發(fā)涕俗,是觸發(fā)上一層的onTouchEvent方法舰始。

這里的概念都不能死記硬背,需要結(jié)合上下文去理解咽袜。

某一層想自己處理,不回傳了枕稀,怎么辦询刹?(onTouchEvent)

onTouchEvent是從內(nèi)向外回傳,那么萎坷,我們先來看最內(nèi)層view的onTouchEvent凹联,代碼如下

//view的onTouchEvent代碼
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.v("hcy","view:onTouchEvent:"+event.getAction());
//        return super.onTouchEvent(event);
        return true;
    }

true,表示自己處理哆档,不會往上回傳蔽挠。false,super表示不自己處理,需要回傳

view group的onTouchEvent,代碼如下

//view group的onTouchEvent代碼
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.v("hcy","viewGroup:onTouchEvent:"+event.getAction());
//        return super.onTouchEvent(event);
        return true;
    }

view group的結(jié)論與view的相同澳淑。都是:true比原,表示自己處理,不會往上回傳杠巡。false,super表示不自己處理量窘,需要回傳。
??activity沒有上一層氢拥,不需要回傳蚌铜。所以,activity的onTouchEvent嫩海,不需要去考慮

那么冬殃,結(jié)論就如下表格:

return true false super.onTouchEvent(event)
view 自己處理 不處理 不處理
view group 自己處理 不處理 不處理

到這里,事件的傳遞基本上就說完了叁怪。完整的流程圖如下:

完整的流程圖.png

更簡單的理解:

true false super
dispatch 中斷 不分發(fā) 正常流程
Intercept 攔截 不不攔截 正常流程
onTouchEvent 處理 不處理 正常流程

dispatch:是否分發(fā)

Intercept:是否攔截

onTouchEvent:是否自己處理

true:真的

false:假的

分發(fā)需要額外單獨記憶审葬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市骂束,隨后出現(xiàn)的幾起案子耳璧,更是在濱河造成了極大的恐慌,老刑警劉巖展箱,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旨枯,死亡現(xiàn)場離奇詭異,居然都是意外死亡混驰,警方通過查閱死者的電腦和手機攀隔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栖榨,“玉大人昆汹,你說我怎么就攤上這事∮ぴ裕” “怎么了满粗?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長愚争。 經(jīng)常有香客問我映皆,道長,這世上最難降的妖魔是什么轰枝? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任捅彻,我火速辦了婚禮,結(jié)果婚禮上鞍陨,老公的妹妹穿的比我還像新娘步淹。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布缭裆。 她就那樣靜靜地躺著键闺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪幼驶。 梳的紋絲不亂的頭發(fā)上艾杏,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音盅藻,去河邊找鬼购桑。 笑死,一個胖子當(dāng)著我的面吹牛氏淑,可吹牛的內(nèi)容都是我干的勃蜘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼假残,長吁一口氣:“原來是場噩夢啊……” “哼缭贡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辉懒,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤阳惹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后眶俩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莹汤,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年颠印,在試婚紗的時候發(fā)現(xiàn)自己被綠了纲岭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡线罕,死狀恐怖止潮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钞楼,我是刑警寧澤喇闸,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站询件,受9級特大地震影響燃乍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雳殊,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窗轩。 院中可真熱鬧夯秃,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至色建,卻和暖如春哺呜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背箕戳。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工某残, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陵吸。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓玻墅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壮虫。 傳聞我的和親對象是個殘疾皇子澳厢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

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