題目如下:View事件傳遞;事件是從哪里到達(dá)Activity的?ViewRootImpl的作用?有A、B兩個Button,各自設(shè)置了OnClickListener,在A上按下,移動到B上抬起,會觸發(fā)OnClickListener么?為何?UP事件誰接收到了?OnClickListener觸發(fā)的條件是哪些?
1.1?View事件傳遞;事件是從哪里到達(dá)Activity的?
這個以后專門寫一篇文章單獨(dú)分析事件如何從屏幕點(diǎn)擊最終到達(dá)Activity的。
1.2 基本三大作用:
作為WindowManager和DecorView的紐帶,橋梁。
完成View的繪制過程,包括measure,layout,draw過程。
向DecorView分發(fā)收到的用戶發(fā)起的Event事件,比如按鍵、觸屏事件等。
1.3? 我們先用代碼驗(yàn)證,然后再結(jié)合源碼來分析

按照在A按鈕按下,然后一直移動 直到B按鈕位置才抬起來 結(jié)果是:
剛按下時候觸發(fā)A按鈕的 ACTION_DOWN,然后在A范圍內(nèi)移動,觸發(fā)ACTION_MOVE,當(dāng)不在A范圍內(nèi)移動時,沒有事件觸發(fā),然后又移動到A范圍內(nèi),依然ACTION_MOVE。最后再移動到B按鈕上抬起,觸發(fā)A按鈕的ACTION_UP。過程中沒有觸發(fā)B按鈕任何事件。



不會觸發(fā)OnClickListener
1.4 UP事件被A按鈕收到了。
1.5 源碼來分析:
首先看不會觸發(fā)OnClickListener原因。

而Onclick事件是在UP事件中觸發(fā)

可以看到邏輯也比較簡單:當(dāng)觸發(fā)ACTION_UP事件時,也就是手指抬起時,當(dāng)View處于Pressed狀態(tài)。就會觸發(fā)performClickInternal()。這里面也會調(diào)用performClick。也就是回調(diào)onClick。
所以結(jié)論:當(dāng)A按鈕移出View后再B后抬起是不會觸發(fā)onClick事件的。
UP事件沒有被B按鈕處理是B都沒有處理ACTION_DOWN事件(這是一個事件序列的開端)。顯然是不會觸發(fā)UP事件的。
1.6 OnClickListener觸發(fā)的條件是哪些?
先給出結(jié)論?
設(shè)置了setOnClicklistener
View沒有重寫OnTouchEvent(默認(rèn)情況下 這個方法返回值是clickable,也就是說View如果是可點(diǎn)擊的,那么就會消耗事件)
手指沒有移動出View的范圍
有抬起動作。
現(xiàn)在主要分析下如果View重寫OnTouchEvent的情況。為什么就不會觸發(fā)了OnClick事件了。

當(dāng)我重寫onTouchEvent 無論之間返回false或者ture時,都不會觸發(fā)了onClick事件

此時的日志始終沒有打印。其實(shí)想想也是我們的onClick回調(diào)是在View#onTouchEvent的ACTION_UP那一段代碼觸發(fā)的。我們點(diǎn)擊按鈕時候都沒觸發(fā)View的onTouchEvent方法怎么會進(jìn)行onClick回調(diào)呢。
當(dāng)自定義View時候重寫了onTouchEvent方法后,還想要響應(yīng)onClick回調(diào)時,可以在ACTION_UP里面手動調(diào)用
return true;

當(dāng)返回return super.onTouchEvent(event);

現(xiàn)象:onClick 會觸發(fā)兩次
當(dāng)返回return false; 不會觸發(fā),即使調(diào)用了performClick(); 因?yàn)閞eturn false代表View不處理此事件了。
