安卓面試必問一View的事件分發,安卓view事件分發
真心面試要準備很多東西,其實我覺得程式員何必難為程式員,有可能面試官,自己都不知道..................但是為了證明你學過安卓,你得答出來不是,在加上面試也同時給你複習基礎,如果你看了這篇文章 我覺得你最好用自己的語言群組織下,經過大腦組織過得東西,記憶才快。
面試官問:請你講解一下事件分發是怎麼回事?
小菜鳥:那我就用一個小例子講解下...........
首先:
1.測試優先順序結果是 Ontouch>OnClick我先給一個button 註冊一個點擊事件(onClick),和一個touch事件(setOnTouchListener) 並且列印輸出結果 touch事件判斷的比較多 比如按下 抬起,移動事件 。然後我就點擊一下button 列印結果是Ontouch事件先執行,然後執行點擊事件。 Ontouch事件執行兩次,一次是ACTION_DOWN,一次是ACTION_UP 然後事件傳遞到OnClick中
2.通過改OnTouch返回值 可以把事件傳遞截止
Ontouch事件是有返回值的,我就嘗試把返回值改成true 我發現Onclick 事件並沒有執行了,這是因為onTouch方法返回true就認為這個事件被onTouch消費掉了,因而不會再繼續向下傳遞
3.從源碼分析從源碼中,如果我點擊任何一個控制項,他就一定會調用dispatchTouchEvent,當我們點擊Button的時候,就會調用這個方法,如果button並沒有發生,他就會傳遞給父類textView,如果textView 也沒有,那就繼續去父類找View裡面, 知道找到那個方法
對於View中的dispatchTouchEvent方法,在這個方法內,首先是進行了一個判斷,裡面有三個條件,如果這三個條件都滿足,就返回true,否則就返回onTouchEvent方法執行的結果。
對於第一個條件是一個mOnTouchListener變數,這個變數是在View中的setOnTouchListener方法裡賦值的,也就是說只要我們給控制項註冊了touch事件,mOnTouchListener就一定被賦值了。
第二個條件是判斷當前點擊的控制項是否是enable的,按鈕預設都是enable的,因此這個條件恒定為true。
第三個條件最為關鍵,mOnTouchListener.onTouch(this, event),其實也就是去回調控制項註冊touch事件時的onTouch方法。也就是說如果我們在onTouch方法裡返回true,就會讓這三個條件全部成立,從而整個方法直接返回true。如果我們在onTouch方法裡返回false,就會再去執行onTouchEvent(event)方法。
4.onTouchEvent方法
如果我們的控制項是可以點擊的,就會進入到switch判斷中去,而如果當前的事件是抬起手指,則會進入到MotionEvent.ACTION_UP這個case當中。在經過種種判斷之後,會執行到performClick()方法。
對於performClick()方法,只要mOnClickListener不是null,就會去調用它的onClick方法。
而剛剛說過,當我們通過調用setOnClickListener方法來給控制項註冊一個點擊事件時,就會給mOnClickListener賦值。然後每當控制項被點擊時,都會在performClick()方法裡回調被點擊控制項的onClick方法。
這樣View的整個事件分發的流程就讓我們搞清楚了!
5.touch事件分發的三個問題:1. onTouch和onTouchEvent有什麼區別,又該如何使用?
從源碼中可以看出,這兩個方法都是在View的dispatchTouchEvent中調用的,onTouch優先於onTouchEvent執行。如果在onTouch方法中通過返回true將事件消費掉,onTouchEvent將不會再執行。
另外需要注意的是,onTouch能夠得到執行需要兩個前提條件,第一mOnTouchListener的值不可為空,第二當前點擊的控制項必須是enable的。因此如果我們有一個控制項是非enable的,那麼給它註冊onTouch事件將永遠得不到執行。對於這一類控制項,如果我們想要監聽它的touch事件,就必須通過在該控制項中重寫onTouchEvent方法來實現。