Android事件分發機制「不詳解」

話說:只要掌握了事件分發機制,就能找到好工做、升職加薪、當上總經理、出任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()就會被調用,如此反覆,直到事件被處理。事件

一些結論(摘抄自《Android開發藝術探索》)

  1. 同一個事件序列是指從手指觸摸屏幕的那一刻起,到手指離開屏幕那一刻結束,在這個過程當中產生的一系列事件,這一系列事件以down事件開始,以up事件結束,中間可能有一些move事件。開發

  2. 正常狀況下,一個事件序列只能被一個View攔截並消耗。

  3. 某個View一旦決定攔截,那麼這一個事件序列都只能由它來處理(若是事件序列可以傳遞給它的話),而且它的onInterceptTouchEvent()不會再被調用。

  4. 某個View一旦開始處理事件,若是它不消耗ACTION_DOWN事件(onTouchEvent()返回了false),那麼同一事件序列中的其餘事件都不會再交給它處理,而且事件將從新交由它的父元素去處理,及父元素的onTouchEvent()會被調用。

  5. 若是View不消耗ACTON_DOWN之外的其餘事件,那麼這個點擊事件會消失,此時父元素的onTouchEvent()並不會被調用,而且當前View能夠持續收到後續的事件。最終這些消失的點擊事件會傳遞給Activity處理。

  6. ViewGroup默認不攔截事件。onInterceptTouchEvent()方法默認返回false。

  7. View沒有onInterceptTouchEvent()方法,一旦有事件傳遞給它,那麼它的onTouchEvent()方法就會被調用。

  8. View的onTouchevent()默認都會消耗事件(返回true),除非它是不可點擊的(clickable和longClickable同時爲false)。

  9. View的enable屬性不影響onTouchEvent()的默認返回值。哪怕一個View是disable狀態的,只要它的clickable和longClickable有一個爲true,那麼它的onTouchEvent()就返回true。

  10. onClick會發生的前提是當前View是可點擊的,而且它收到了down和up的事件。

  11. 事件傳遞的方向是由外向內的,即事件老是先傳遞給父元素,而後由父元素分發給子View。

  12. 當面對ACTION_DOWN事件時,ViewGroup老是會調用本身的onInterceptTouchEvent()方法來詢問本身是否要攔截該事件。

  13. 當ACTION_UP方法發生時,會觸發performClick()方法,若是View設置了onClickListener,那麼performClick()方法內部會調用它的onClick()方法。

流程圖

爲了把事件分發機制研究明白,我畫了一張流程圖。

流程圖地址

就到這裏了。
若是有什麼問題,你們能夠在評論中提出來,咱們一塊兒討論。
加油,各位!

本文來自:http://qiaoyunrui.github.io/2016/05/23/androidDispatchEvent/

相關文章
相關標籤/搜索