一步步探索學習Android Touch事件分發傳遞機制(一)

Android TouchEvent 簡介

1.探究對象簡介
  • Android的屏幕觸摸事件在Android官方API中由類MotionEvent來描述,不一樣的觸摸事件對應不一樣的事件類型。
  • 如:ACTION_DOWN;ACTION_UP;ACTION_MOVE;ACTION_CANCEL
  • 每一個事件對應都有本身的傳遞路徑,從產生到傳遞到最終被消費(終止傳遞)。而它們的傳遞的載體就是整顆View樹。
  • 畢竟這是屏幕觸摸事件,而屏幕上顯示的正是由不一樣的ViewGroup和各式各樣的View組成的View樹。
  • 咱們須要探索的就是一個TouchEvent的整個從產生到被消費的整個傳遞過程和機制。
  • 裏面咱們核心須要探索的是關於View和ViewGroup類中的如下幾個處理觸摸事件的方法的處理流程。post

    ViewGoup: dispatchTouchEvent(); onInterceptTouchEvent(); onTouchEvent()
    View:dispatchTouchEvent(); onTouchEvent()
    Activity:dispatchTouchEvent(); onTouchEvent()學習

    2.探索Touch事件的傳遞機制的意義
  • 經過了解和探究Android Touch事件的傳遞機制,可讓咱們明白觸摸事件究竟是怎麼產生以及如何被處理的spa

  • 能夠在此基礎上深入的清楚整個View樹處理觸摸事件的流程,從而對咱們如何避免觸摸事件衝突,點擊事件攔截等業務開發需求時,作到成竹在胸。
    -像咱們平時常遇到的一些自定義View嵌套時點擊事件,觸摸手勢衝突的問題的解決都依賴於咱們對這個機制的認識。

說明:
1.爲了便於理解和整文的清晰明瞭,本篇文章只是分析一種事件類型:ACTION_DOWN事件的傳遞過程,置於ACTION_MOVE,ACTION_UP事件會在下一篇文章《一步步探索學習Android Touch事件分發傳遞機制(二)》中分析
2.知其然,還須知其因此然,我會在《一步步探索學習Android Touch事件分發傳遞機制(三)》中,經過分析Android源碼來解釋探索整個Android Touch事件傳遞分發機制。設計

寫個Demo去探索

  • 廢話很少說,「絕知此事要躬行」,因此直接寫個Demo打log出來看,其實這個機制會很清晰明瞭。
  • 各位看官,看log,找規律!
1.界面&代碼
  • 這裏寫圖片描述
    這裏寫圖片描述

  • 如上圖,能夠看到,我在Activity裏面寫了三個View(ViewGroup)。ViewGroup1包裹着ViewGroup2,ViewGroup2包裹着一個TextView。這些View都是我自定義的。cdn

  • 代碼部分就只是重寫他們的dispatchTouchEvent();onInterceptTouchEvent()和onTouchEvent方法,返回不一樣的值,打印log,看整個事件的傳遞流程。

    注:只有ViewGroup有onInterceptTouchEvent()方法。至於爲何這麼設計,在後面探索完以後會交代。對象

2.view的代碼
  • activity的代碼
    blog

    activity的代碼
    activity的代碼

  • viewGroup的代碼
    事件

    viewGroup的代碼
    viewGroup的代碼

  • viewGroup2的代碼
    圖片

    viewGroup2的代碼
    viewGroup2的代碼

  • view的代碼
    開發

    view的代碼
    view的代碼

3.打log,看規律,識機制
  • 默認狀況下,這些方法都是return super(即父類的默認實現的)。因此先看一下默認狀況下,一個ACTION_DOWN事件是怎麼傳遞的。給最裏面的View一個觸摸,產生ACTION_DOWN事件。

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 能夠看到傳遞流程,能夠用流程圖表示爲:
      類U型Touch事件傳遞機制
      類U型Touch事件傳遞機制
  • 而後咱們探索dispatchTouchEvent()方法,令其return false(這裏以ViewGroup2的dispatchTouchEvent()方法爲例),log以下:

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 能夠看到傳遞流程,能夠用流程圖表示爲:
      這裏寫圖片描述
      這裏寫圖片描述
    • 規律:當dispatchTouchEvent()返回false時,會將事件傳遞給上一級的View的onTouchEvent()方法處理。因爲Activity已經沒有比它更高一級的View,因此若是是Activity的dispatchTouchEvent()方法return false的話,事件會直接被消費掉(即終止傳遞)
  • 接着讓dispatchTouchEvent()方法return true(這裏以ViewGroup2的dispatchTouchEvent()方法爲例),log以下:

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 能夠看到傳遞流程,能夠用流程圖表示爲:
      這裏寫圖片描述
      這裏寫圖片描述
    • 規律:若是dispatchTouchEvent()方法返回true時,事件會被消費掉,再也不傳遞。
  • 而後咱們探索一下onTouchEvent()方法,令其return false,(這裏以最裏層的View的onTouchEvent()方法爲例),log以下:

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 能夠看到傳遞流程,能夠用流程圖表示爲:
      這裏寫圖片描述
      這裏寫圖片描述
    • 規律:若是onTouchEvent()方法返回false時,跟默認return super是同樣的,都會一直向上傳遞到上一級view的onTouchEvent()方法。
    • 事實上,onTouchEvent()方法super父類的默認實現返回的就是false,因此是同樣的。關於源碼的分析,請詳見《一步步探索學習Android Touch事件分發傳遞機制(三)》。
  • 而後咱們讓onTouchEvent()方法return true,(這裏以最裏層的View的onTouchEvent()方法爲例),log以下:

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 能夠看到傳遞流程,能夠用流程圖表示爲:
      這裏寫圖片描述
      這裏寫圖片描述
    • 規律:若是onTouchEvent()方法返回true時,事件會被消費掉,再也不傳遞。跟dispatchTouchEvent()return true的時候相似。
  • 最後,咱們來探索onInterceptTouchEvent()方法,令其return false,(這裏以最裏層的ViewGroup2的onInterceptTouchEvent()方法爲例),log以下:

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 規律:這裏就不貼流程圖了,可是能夠看到onInterceptTouchEvent()方法return false和return super是同樣的。都是默認將觸摸事件傳給下一級view的dispatchTouchEvent()方法。
    • 事實上,onInterceptTouchEvent()方法super父類的默認實現返回的就是false,因此是同樣的。關於源碼的分析,請詳見《一步步探索學習Android Touch事件分發傳遞機制(三)》。
  • 最後,咱們讓onInterceptTouchEvent()方法return true,(這裏以最裏層的ViewGroup2的onInterceptTouchEvent()方法爲例),log以下:

    • log:
      這裏寫圖片描述
      這裏寫圖片描述
    • 能夠看到傳遞流程,能夠用流程圖表示爲:
      這裏寫圖片描述
      這裏寫圖片描述
    • 規律:若是onInterceptTouchEvent()方法返回true時,Touch事件會被直接傳遞給ViewGroup本身的onTouchEvent()方法處理。

吾日三省吾身-- --總結概括

1.對於dispatchTouchEvent()方法:

  • return true:消費掉事件,終止傳遞。
  • return false: 將事件傳遞給上一級View的onTouchEvent()方法。若是是Activity的dispatchTouchEvent()方法,則也是消費掉事件,終止傳遞。
  • return super:若是是Activity,則傳給下一級view(viewGroup)的dispatchTouchEvent;若是是ViewGroup,則傳給本身的onInterceptTouchEvent();若是是View,則傳給本身的onTouchEvent().

2.對於onTouchEvent()方法:

  • return true:消費掉事件,終止傳遞。
  • return false/super:將事件傳遞給上一級view的onTouchEvent()方法。

3.對於onInterceptTouchEvent()方法:

  • return true:將事件傳遞給ViewGroup本身的onTouchEvent()方法處理。
  • return false/super:將事件傳遞給下一級View的dispatchTouchEvent()。
  • 回到以前咱們的一個問題,爲何只有ViewGrouponInterceptTouchEvent()方法呢,從上面的整個觸摸事件分發傳遞機制咱們能夠發現,ViewGroup自己的dispatchTouchEvent()方法不管返回什麼都不能將事件傳遞給本身的onTouchEvent()方法處理,那就只好設計了一個這樣子的方法,做爲攔截器,攔截事件交給本身處理了。只要onInterceptTouchEvent()return true就能夠實現觸摸事件攔截。
相關文章
相關標籤/搜索