先來看一個例子
在一個界面上有一個按鈕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-