自定義view原始碼分析之事件分發01

weixin_33976072發表於2017-01-19

很多時候都想弄清楚view的原始碼,很多時候在自定義view的時候都是感覺到無盡的迷茫,很多時候看到炫酷的view總是心生羨慕之情,這次我來了,我自己來開始我的原始碼分析之路。

問題

人都喜歡簡單明瞭的工作流程圖,那麼我就上自己理解的流程圖,由簡單到複雜,一步步走進自定義view的心裡。

最想知道的流程是:

  1. 從點選螢幕開始,是怎麼樣響應我的點選事件的?
  2. 介面上顯示的view,又是怎麼樣呈現在我們面前的(記得有一次被面試問到: 你最常用的listview是怎麼顯示出來的?)?

懷著問題,開始開車上路。

事件分發

點選事件分發的流程:

1,螢幕感測器->Activity ->ViewGroup->View 。
外層的touch事件的呼叫順序為:

  Action_Down傳遞:
      dispatchTouchEvent(Activity) ->dispatchTouchEvent(ViewGroup) -> onInterceptTouchEvent(ViewGroup)->dispatchTouchEvent(View) -> onTouch(View)->onTouchEvent(View)->onClick()(View) 
  如果不消費:
      onTouchEvent(View)->onTouchEvent(ViewGroup)->onTouchEvent(Activity)

2,原始碼大體流程


3100903-b76c2938d5a79a13.png
workflow類圖

其中Activity的原始碼:

  public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

getWindow()返回的便是一個Window的抽象類,具體實現便是PhoneWindow類,具體跟蹤原始碼便能找到。
PhoneWindow原始碼:

@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);
}

但是PhoneWindow屬於framework層了,想繼續跟蹤便需要下載原始碼檢視原始碼:老司機的檢視方法:http://blog.csdn.net/a740169405/article/details/50019273

繼續跟蹤framework原始碼到DecorView類,這個類便最頂層的,它繼承至ViewGroup,根據遞迴,進而便順利成章的將事件分發到各個ViewGroup和View。

3100903-fd1a217db9ed666c.png
DecorView原始碼

DecorView原始碼:

 public boolean superDispatchTouchEvent(MotionEvent event) {
      return super.dispatchTouchEvent(event);
 }

事件分發的大體流程以及大體原始碼跟蹤到此結束,瞭解了流程,心理是不是就有個底了?分析起來應該會順暢很多了,下面就是開始ViewGroup和View的原始碼解析了。

相關文章