Android6.0觸摸事件分發機制解讀

來源:互聯網
上載者:User

標籤: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觸摸事件分發機制解讀

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.