在Android中,人們主要經過手指與系統交互。Android把全部的touch事件都被封裝成MotionEvent來進行處理,其中包括了手指點擊的位置,時間等信息。其事件類型主要包括:ACTION_DOWN,ACTION_UP,ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP,ACTION_CANCEL。函數
這些事件是有觸發順序的,下面舉兩個栗子:spa
爲了處理這些事件,Android定義了三種方法:blog
當一個事件被觸發,事件的傳遞從Activity.dispatchTouchEvent()開始,一直從最外層的父view開始向裏面的子view傳遞,直到被攔截。在傳遞過程當中,view能夠經過onInterceptTouchEvent()函數進行攔截,一旦父view攔截了該事件,則再也不向下傳遞。事件
若是被觸發的事件被傳遞至最內層的view,一直未被攔截消費,則會反向向外傳遞,這時候父view能夠經過onTouchEvent函數對事件進行消費,直到activity。另外,若是被觸發的ACTION_DOWN事件在某一層未被消費,那麼接下來的事件是沒法被傳遞進來的。開發
下面咱們來看幾個例子:it
Case 1 手指點擊在view上,父View(ViewGroup)和View都不消費事件,最終返回給activity消費。io
以ACTION_DOWN事件爲例,ACTION_DOWN事件沿着圖中黑色箭頭逐層傳遞。在開發過程當中,咱們一般會爲view或者viewGroup設置監聽器來捕獲view事件,listener的onTouch方法會在onTouchEvent以前執行。在分發傳遞過程當中,不管哪一個方法返回true,都表示傳遞中止;若是返回false,則表示繼續傳遞下去。event
從圖上能夠看出,ACTION_DOWN事件通過activity—>ViewGroup—>View—>ViewGroup—>activity一直未被ViewGroup和View消費處理,又回到了activity中。那麼隨後的ACTION_MOVE和ACTION_UP事件只會沿着綠色箭頭傳遞,再也不沿着ACTION_DOWN事件的路線傳遞了。List
Case 2 手指點擊在父View和子View之間的空隙中,並未點擊在子View上。同上一個例子同樣,ViewGroup中並未消費該事件,返回給了activity。方法
這裏用戶並未點擊到ViewGroup中的view,而是點擊在了ViewGroup和View之間的空隙處。同上一個例子相同,ViewGroup並未處理ACTION_DOWN事件,而是返回給了activity處理。
Case 3 單擊view後,在view中處理消費了ACTION_DOWN事件。
從圖上能夠看到,ACTION_DOWN事件沿着黑色箭頭方向逐層向內部傳遞,直到在view的onTouchEvent中消費了該事件,並返回true表示再也不向下傳遞。隨後的事件ACTION_MOVE和ACTION_UP將會沿着綠色箭頭傳遞,直到到達view的onTouchEvent方法。
Case 4 單擊view,可是並不在view中處理ACTION_DOWN事件,而是讓它傳遞到ViewGroup中處理。
ACTION_DOWN事件通過ViewGroup,ViewGroup並未攔截而是傳遞給View。View並未消費該事件而是回傳給了ViewGroup,在ViewGroup中消費該事件。
Case 5 單擊view,在ViewGroup中攔截ACTION_DOWN事件並消費
ACTION_DOWN事件沿着黑色箭頭分發傳遞,在ViewGroup中對它進行攔截(返回true),因此就再也不繼續向view傳遞ACTION_DOWN事件了。而後在ViewGroup的onTouchEvent方法中消費了該事件,並返回true表示事件已消費。隨後的ACTION_MOVE和ACTION_UP事件將沿着綠色箭頭傳遞,直抵最後的消費方法onTouchEvent,而並不通過攔截事件。