一張圖搞定安卓事件傳遞機(jī)制

先來看一個例子

在一個界面上有一個按鈕1,現(xiàn)在在按鈕1上覆蓋一個按鈕2,然后點擊按鈕2,請問底下的按鈕1能拿到點擊事件嗎?

要搞懂這個問題,首先我們必須對安卓的事件分發(fā)機(jī)制有一個基本的了解,接下來我用3W1H的方式說明:

事件傳遞機(jī)制
  • 分發(fā):表示事件未找到消費地點,將交給自身的下一函數(shù)處理;攔截:表示事件不再傳遞給子類;消費:表示事件找到消費地點,事件傳遞完結(jié)
  • 從圖上我們可以知道,安卓的事件分發(fā)機(jī)制其實就容器和控件通過分發(fā)和攔截,沿著視圖樹向下傳遞觸摸事件,當(dāng)?shù)竭_(dá)底層控件或者被攔截時,表示事件不在線下分發(fā),繼而沿著視圖樹向上尋找真正消費的地方的過程。

在回來看看之前的例子,它的視圖樹應(yīng)該是這樣的:


視圖樹

分析

  • 從圖中我們可以看到Button2和Button1是并列關(guān)系,而且Button2優(yōu)先于Button1
  • 問題問的是button1是否會拿到觸摸事件,Button本身已經(jīng)是最小的單位了,這里分析就是View中事件傳遞的問題
  • 事件傳遞中View擁有dispatchTouchEvent和onTouchEvent兩個方法,即分發(fā)和消費。
  • 這里的Button是原生的控件并未人為干擾,View控件的事件觸發(fā)順序是先執(zhí)行onTouch方法,在最后執(zhí)行onClick方法,如果onTouch返回true,則不會調(diào)用onClick方法。 onTouch和onTouchEvent以及onClick的順序,有什么區(qū)別,又該如何使用?

當(dāng)用戶點擊Button2時候,事件會這么傳遞:

Button2事件傳遞

因此我們可以知道,如果點擊了Buttn2,點擊事件會在Button2的onClick事件中消費掉,Button1是拿不到點擊事件的,也拿不到任何觸摸事件,除非在Button2中重寫了分發(fā)方法,不走super方法,直接返回true,那么Button1中將拿到觸摸事件。

Button1拿到事件

-END-

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容