話說:只要掌握了事件分發機制,就能找到好工做、升職加薪、當上總經理、出任ceo、迎娶白富美。
哈哈哈,不囉嗦,讓咱們開始。java
和事件分發機制密切相關的三個方法分別是:android
public boolean dispatchTouchEvent(MotionEvent ev)
git
用來進行事件的分發。若是事件可以傳遞到當前View,此方法必定會被調用,返回結果受當前View的onTouchEvent()
和下級View的diapatchTouchEvent()
方法的影響,表示是否消耗當前事件。github
public boolean onInterceptTouchEvent(MotionEvent event)
ui
用來判斷是否攔截某個事件,若是當前View攔截了某個事件,那麼在同一個事件序列當中,此方法不會被再次調用,返回結果表示是否攔截當前事件。spa
public boolean onTouchEvent(MotionEvent event)
code
在dispatchTouchEvent()
中調用,用來處理點擊事件,返回結果表示是否消耗當前事件,若是不消耗,則在同一個事件序列中,當前View沒法再次接收事件。orm
public boolean dispatchTouchEvent(MotionEvent event) { boolean consume = false; if(onInterceptTouchEvent(ev)) { consume = onTouchEvent(ev); } else { consume = child.dispatchTouchEvent(ev); } return consume; }
經過上面的僞代碼,咱們大體能夠了解點擊事件的傳遞規則:對於一個根ViewGroup來講,點擊事件產生後,首先會傳遞給它,這是它的
dispatchTouchEvent()
就會被調用,若是這個ViewGroup的onInterceptTouchEvent()
方法返回true就表示它要攔截當前事件,接着事件就會交給該ViewGroup處理,即執行onTouchEvent()
方法。若是onInterceptTouchEvent()
方法返回false就表示它不攔截該當前事件,這時事件就會繼續傳遞給它的子元素,接着子元素的dispatchTouchEvent()
就會被調用,如此反覆,直到事件被處理。事件
同一個事件序列是指從手指觸摸屏幕的那一刻起,到手指離開屏幕那一刻結束,在這個過程當中產生的一系列事件,這一系列事件以down事件開始,以up事件結束,中間可能有一些move事件。開發
正常狀況下,一個事件序列只能被一個View攔截並消耗。
某個View一旦決定攔截,那麼這一個事件序列都只能由它來處理(若是事件序列可以傳遞給它的話),而且它的onInterceptTouchEvent()
不會再被調用。
某個View一旦開始處理事件,若是它不消耗ACTION_DOWN事件(onTouchEvent()
返回了false),那麼同一事件序列中的其餘事件都不會再交給它處理,而且事件將從新交由它的父元素去處理,及父元素的onTouchEvent()
會被調用。
若是View不消耗ACTON_DOWN之外的其餘事件,那麼這個點擊事件會消失,此時父元素的onTouchEvent()並不會被調用,而且當前View能夠持續收到後續的事件。最終這些消失的點擊事件會傳遞給Activity處理。
ViewGroup默認不攔截事件。onInterceptTouchEvent()
方法默認返回false。
View沒有onInterceptTouchEvent()
方法,一旦有事件傳遞給它,那麼它的onTouchEvent()
方法就會被調用。
View的onTouchevent()
默認都會消耗事件(返回true),除非它是不可點擊的(clickable和longClickable同時爲false)。
View的enable屬性不影響onTouchEvent()
的默認返回值。哪怕一個View是disable狀態的,只要它的clickable和longClickable有一個爲true,那麼它的onTouchEvent()
就返回true。
onClick會發生的前提是當前View是可點擊的,而且它收到了down和up的事件。
事件傳遞的方向是由外向內的,即事件老是先傳遞給父元素,而後由父元素分發給子View。
當面對ACTION_DOWN事件時,ViewGroup老是會調用本身的onInterceptTouchEvent()
方法來詢問本身是否要攔截該事件。
當ACTION_UP方法發生時,會觸發performClick()
方法,若是View設置了onClickListener,那麼performClick()
方法內部會調用它的onClick()方法。
爲了把事件分發機制研究明白,我畫了一張流程圖。
就到這裏了。
若是有什麼問題,你們能夠在評論中提出來,咱們一塊兒討論。
加油,各位!
本文來自:http://qiaoyunrui.github.io/2016/05/23/androidDispatchEvent/