Android事件分發基礎

原文首發於微信公衆號:躬行之(jzman-blog),歡迎關注交流!

Android 事件分發機制是比較重要的一塊內容,總結一下 Android 事件分發的一些知識,計劃分爲四篇文章來寫,內容如下:

Android事件分發

本篇是第一篇,希望從整體流程上敘述一下大致的分發過程,使讀者能夠對事件分發有個初步的瞭解,內容如下:

  1. View 與 ViewGroup
  2. MotionEvent 對象
  3. View 的事件分發

View 與 ViewGroup

Android 應用中的所有組件都繼承了 View 類,View 類是 Android 中所有 UI 組件的基類,View 有一個重要的子類是 ViewGroup,ViewGroup 通常作爲其他 View 的容器使用,裏面可以包含普通的 View,也可以是其他 ViewGroup,通過 View 與 Viewgroup 的這種關係共同構成了整個 View 樹的結構,如 LinearLayout 不僅是一個 View ,還是一個 ViewGroup,裏面可以包含各種 View,當然這個 View 也可以是 ViewGroup,以此類推。

在 Android 設備中,操作主要依靠的就是各種手勢,比如滑動、拖動、單擊等各種操作,這一系列操作可以很方便的與 Android 設備進行交互,前面可知不同 View 處於不同的層級,問題來了,那麼當我們操作的時候如何正確的讓特定的 View 響應某種操作呢,不同的 View 之間會不會發生滑動衝突呢,答案是肯定的,解決這樣的問題就必須的充分了解 View 的工作機制、各種事件的分發過程以及具體的分發對象。

MotionEvent對象

Android 中事件分發的是 MotionEvent 對象,MotionEvent 中封裝了許多與各種事件發生位置相關的函數以及各種相關的事件類型,每個 MotionEvent 都包含一系列動作,比如當手指觸摸屏幕的一瞬間,系統就會產生一系列的觸摸事件對象,每個觸摸事件對象都代表這不同的動作,比如按下滑動擡起等動作,這些動作分別對應着 ACTION_DOWN、ACTION_MOVE、ACTION_UP 等具體的事件,這一系列事件一般是由 ACTION_DOWN 事件開始,中間若干 ACTION_MOVE 事件,最後以 ACTION_UP 結束,此外,如果事件被攔截還會觸發 ACTION_CANCEL 事件。總之,Android 事件分發的對象就是 MotionEvent 對象,當 MotionEvent 對象產生之後,系統會將這個事件分發給最終能夠消費此事件的 View。

View的事件分發

Android 中的事件分發實際上指的就是 View 的事件分發,View 的事件分發主要是下面三個方法:

  1. dispatchTouchEvent()
  2. interceptTouchEvent()
  3. onTouchEvent()

這三個方法分別對應事件的分發、事件的攔截以及事件的處理,另外,View 沒有 interceptTouchEvent() 方法,一方面 View 裏面沒有其他子 View 不需要攔截事件,另一方面可以理解爲 View 的 interceptTouchEvent() 方法返回 true,事件本身由該 View 攔截,消不消費是 onTouchEvent() 的事,反正,View 不考慮事件的攔截。

Android 事件分發從 Activity 的 dispatchTouchEvent() 方法開始,通過一系列傳遞分發給 ViewGroup 的 dispatchTouchEvent() 方法,如果當前 ViewGroup 不攔截事件,則繼續向子 View 分發事件,然後以此類推直到被哪個 View 處理,如果沒有任何 View 處理該事件,當事件由父 View 向子 View 傳遞到最深層次的 View 時,事件將向父 View 的方向回傳事件,最後交由 Activity 的 onTouchEvent() 進行處理。

如果當前 ViewGroup 攔截該事件,則事件不在向子 View 分發,而是調用其 onTouchEvent() 方法處理事件,當然事件是否處理主要看相應的 onTouchEvent() 方法的返回值,如果 onTouchEvent() 方法返回 true,表示事件就此消費,反之,返回 false 表示事件沒有被消費,將交由父 View 的 onTouchEvent() 方法進行處理,如果父 View 中一直沒有處理,則最後將交由 Activity 的 onTouchEvent() 進行處理。

如果事件在分發過程中被某個 View 處理了,比如說是 ACTION_DOWN 事件,當該事件被處理了,後面的 ACTION_MOVE、ACTION_UP 事件將由處理該事件的那個 View 直接接收,也就是說一旦某個事件被某個 View 處理了,後面的一系列事件不在判斷是否攔截這些事件,而是直接接收,因爲一個完整的事件序列始終以 ACTION_DOWN 事件開始,然後若干 ACTION_MOVE 事件,最後以 ACTION_UP 結束。

總結

Android 事件傳遞機制主要內容大致如上所述,但實際分發流程肯定較爲複雜,下一篇將從源碼角度來看 Android 事件分發機制。
個人微信公衆號:jzman-blog 可以一起交流學習!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章