標籤:isp 影響 script block bsp ber 技術 pre 圖片
本篇博文是Android觸摸事件分發機制系列博文的第一篇,帶領大家從全域掌握Android觸摸事件分發機制。特別聲明的是,本源碼解讀是基於最新的Android6.0版本。
(一)Android6.0源碼解讀之View點擊事件分發機制
(二)Android6.0源碼解讀之ViewGroup點擊事件分發機制
(三)Android6.0源碼解讀之Activity點擊事件分發機制
為什麼要解讀觸摸事件分發機制
1.掌握View事件分發機制
2.為解決View滑動衝突提供理論支援
3.瞭解Android最新源碼改動
Touch觸摸事件
在Android中Touch觸摸事件主要包括點擊(onClick)、長按(onLongClick)、拖拽(onDrag)、滑動(onScroll)等,點擊又包括單擊和雙擊,另外還包括單指操作和多指操作。其中Touch的第一個狀態是 ACTION_DOWN,表示按下了螢幕後,touch將會有後續事件,比如移動、抬起等,一個Action_DOWN,一個ACTION_UP,許多個ACTION_MOVE,就構成了Android中眾多的事件。所有的操作事件首先必須執行的是按下操作(ACTIONDOWN),之後所有的操作都是以此作為前提,當按下操作完成後,接下來可能是一段移動(ACTIONMOVE)然後抬起(ACTION_UP),或者是按下操作執行完成後沒有移動就直接抬起。
● 按下(ACTION_DOWN)
● 移動(ACTION_MOVE)
● 抬起(ACTION_UP)
● 取消手勢(ACTION_CANCEL)
● 滑出螢幕(ACTION_OUTSIDE)
觸摸事件分發機制涉及的三個重要方法
public boolean dispatchTouchEvent(MotionEvent ev)
dispatchTouchEvent用來進行事件的分發。如果事件能夠傳遞給當前的View,那麼此方法一定會被調用,返回結果受當前View的onTouchEvent和下級View的dispatchTouchEvent方法的影響,表示是否消耗當前事件。
public boolean onInterceptTouchEvent(MotionEvent event)
onInterceptTouchEvent是ViewGroup提供的方法,用來判斷是否攔截某個事件,如果當前View攔截了某個事件,那麼在同一個事件序列當中,此方法不會被再次調用,返回結果表示是否攔截當前事件。預設返回false,返回true表示攔截。
public boolean onTouchEvent(MotionEvent event)
onTouchEvent在dispatchTouchEvent方法中調用,用來處理點擊事件,返回結果表示是否消耗當前的事件,如果不消耗,則在同一個事件序列中,當前View無法再次接受到事件。view中預設返回true,表示消費了這個事件。
這三個重要方法的分布情況
在View中包含以下兩個方法:
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent ev);
在ViewGroup中包含以下三個方法:
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onInterceptTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent ev);
在Activity中包含以下兩個方法:
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent ev);
Android觸摸事件分發流程圖
Android觸摸事件流程總結
1.一個事件序列是指從手指觸控螢幕幕開始,到手指離開螢幕結束,這個過程中產生的一系列事件。同一個事件序列是以ACTION_DOWN事件開始,中間含有數量不定的MOVE事件,最終以ACTION_UP事件結束。
2.事件傳遞的順序是:Activity->Window->View,即事件總是先傳遞給Activity,然後在傳遞給Window,最後在傳遞給View,頂級View接收到事件後,就會按照事件分發機制去分發事件。
3.事件的傳遞過程是由外向內的,即事件總是由父元素分發給子項目。
4.正常情況下,一個事件序列只能被一個View攔截且消耗。一旦一個元素攔截了某次事件,那麼同一個事件序列內的所有事件都會直接交給它處理,因此同一個事件序列中的事件不能分別由兩個View同時處理,但是通過特殊手段可以做到,比如一個View將本該自己處理的事件通過onTouchEvent強行傳遞給其他View處理。
5.某個View一旦開始處理事件,如果它不消耗ACTION_DOWN事件,那麼同一事件序列的其他事情都不會再交給它來處理,並且事件將重新交給它的父容器去處理(調用父容器的onTouchEvent方法);如果它消耗ACTION_DOWN事件,但是不消耗其他類型事件,那麼這個點擊事件會消失,父容器的onTouchEvent方法不會被調用,當前view依然可以收到後續的事件,但是這些事件最後都會傳遞給Activity處理。
6.Android點擊事件分發是到達頂級View後(一般是ViewGroup),會調用ViewGroup的dispatchTouchEvent方法,其中它的onInterceptTouchEvent方法如果返回true,則會對事件傳遞進行攔截,事件由ViewGroup處理;如果onInterceptTouchEvent方法返回false,則代表不對事件進行攔截,預設返回false。則此時子View中的dispatchTouchEvent方法將被調用,到此,事件已經由頂級View傳遞給了下一層的View,接下來的過程是一個遞迴迴圈的過程,和頂級View事件分發過程是一致的,直到完成整個事件分發。
針對View、ViewGroup、Activity中的事件分發機制源碼解讀
各位童鞋可以參考下面連結進行系統學習
(一)Android6.0源碼解讀之View點擊事件分發機制
(二)Android6.0源碼解讀之ViewGroup點擊事件分發機制
(三)Android6.0源碼解讀之Activity點擊事件分發機制
Android6.0觸摸事件分發機制解讀