Android觸摸事件傳遞機制

    簡單梳理一下Android觸摸事件傳遞機制的知識點。佈局

1、View與ViewGroup的關係spa

    View和ViewGroup兩者的繼承關係以下圖所示:對象

    View是Android中最基本的一種UI組件,它是全部控件類的基類。View類的做用是能夠在屏幕上繪製一塊矩形區域,並能響應這塊區域的各類事件(如觸摸事件、點擊事件等)。咱們平時使用的各類控件其實都是繼承自View類,在View的基礎上又添加了一些特有的功能。好比TextView能夠用於顯示文本,進一步還能拓展(extends)爲可編輯的文本控件——EditText類或者可點擊的文本控件——Button類。blog

    ViewGroup也是繼承自View類,但它是一種很是特殊的View,由於它能夠做爲一個容器來放置其餘的控件或佈局。咱們經常使用的各類佈局Layout類以及ListView、ScrollView等都是繼承自ViewGroup。繼承

    在討論Android觸摸事件傳遞機制時,咱們這裏說的View特指除了ViewGroup之外的View控件,也就是沒法做爲容器的最小UI單位。接口

2、Android UI層次結構事件

    Android UI層次結構圖和類圖以下圖所示:原型

 

                                                                                       

     

  Activity是Android應用程序的門面和載體,它表明一個完整的用戶界面。Activity提供了一個窗口來繪製各類視圖,即PhoneWindow類。該類繼承自頂層窗口類Window,而且包含一個DecorView類對象。DecorView繼承自FrameLayout(幀佈局),因此本質上是一個ViewGroup,並且是當前活動所放置的所有View的根視圖(RootView)。當咱們建立一個活動時,在活動的onCreate()方法中調用setContentView(R.layout.layout_name)方法就是爲該活動的ContentView部分指定佈局內容從而完成GUI的渲染。源碼

3、事件的類型it

    事件主要分爲觸摸事件和點擊事件。

    一、觸摸事件:對應的是MotionEvent類,主要有如下三種類型:

    ACTION_DOWN:表示用戶手指按下的動做,標誌着觸摸事件的開始。

    ACTION_UP:表示用戶手指離開屏幕的動做,標誌着觸摸事件的結束。

    ACTION_MOVE:表示用戶手指移動的動做。當用戶手指按下屏幕後,在鬆開以前,只要移動的距離超過了必定的閾值即斷定爲ACTION_MOVE動做。實際上,即便是手指很是   輕微的移動也會被系統監測到從而斷定爲ACTION_MOVE動做。

    ps:用戶觸摸屏幕操做由ACTION_DOWN事件開始,結束於ACTION_UP事件,能夠有0次或屢次ACTION_MOVE事件。

 

    二、點擊事件:用戶手指按下→停留若干時間(可長可短)→用戶手指鬆開,這一完整的過程視爲一次點擊事件。能夠看出,觸摸事件先於點擊事件執行。

4、觸摸事件傳遞機制

    該機制主要包含三個角色、三個階段和三個方法。

    一、三個角色分別爲:Activity、View、ViewGroup。

    二、三個階段分別爲:分發(dispatch)、攔截(intercept)和消費(consume)。

    三、三個方法的方法原型分別爲:

    ①public boolean dispatchTouchEvent(MotionEvent e)……對應於分發事件

    ②public boolean onInterceptTouchEvent(MotionEvent e)……對應於攔截事件

   ③public boolean onTouchEvent(MotionEvent e)……對應於消費事件(即處理事件)

    四、解釋:

    由前面的Android UI層次結構分析能夠看出來,一個Activity包含多層視圖:先是窗口(PhoneWindow),接着是根視圖(即DecorView),而後是具體的ContentView;ContentView視圖部分又是各類佈局和控件的嵌套組合。那麼,當用戶作出了觸摸動做時,觸摸事件應當由哪個View或者哪個ViewGroup負責處理呢?這就是觸摸事件傳遞機制要解決的問題。爲了方便,下面會用視圖這一詞代替View或ViewGroup對象。

    ①在Android系統中,全部觸摸事件必須都由dispatchTouchEvent()方法判斷是否進行分發。分發事件至關於「傳遞事件」的一個過程,分發事件的目的就是爲了找到正確的視圖來處理這個觸摸事件。而處理事件的過程就是所謂的消費階段,調用的方法是onTouchEvent()。若是肯定要繼續分發事件,向什麼地方分發呢?若是是ViewGroup,則是向本身的子視圖進行分發;若是是View,向子視圖進行分發本質上其實就是分發給自身。若是dispatchTouchEvent()方法返回true,則表示事件由當前視圖直接進行消費(處理),再也不繼續分發;不然,向子視圖進行分發。

    ②除了分發和消費,還有一個攔截操做。須注意的是:只有ViewGroup能夠攔截觸摸事件,Activity和View只能分發事件和消費事件。這一點其實很是好理解:由於View沒有子視圖可言,因此不存在攔截的操做;而ViewGroup具備子視圖,選擇性地進行攔截事件是有意義的。ViewGroup能夠調用onInterceptTouchEvent()方法來判斷是否攔截該觸摸事件。若是該方法返回true,表示攔截該事件再也不分發給子視圖;不然,表示不攔截事件繼續分發給子視圖。須注意,ViewGroup類默認是不攔截任何觸摸事件的,若是有須要能夠重寫其onInterceptTouchEvent()方法進行選擇性地攔截。

    ③一旦肯定由某個視圖負責處理(即消費)觸摸事件ACTION_DOWN,那麼後續的ACTION_MOVE和ACTION_UP等觸摸事件也會一樣被該視圖捕獲。在消費事件階段,該視圖會調用onTouchEvent()方法。若是該方法返回true,那麼表示事件被成功消費;若是返回false,那麼意味着當前視圖沒有能力消費該觸摸事件,事件會拋給上層的視圖調用其onTouchEvent()方法進行處理。

 

    五、觸摸事件傳遞過程:

    考慮最通常的狀況,即觸摸事件ACTION_DOWN由某個View消費掉的狀況。事件傳遞過程分紅兩步,整個過程都嚴格遵循上述的分發、攔截和消費的原理。以下圖所示:

                                   

  

    ①第一步:先由Activity傳遞到ViewGroup,具體地講就是Activity→PhoneWindow→DecorView(根視圖)。

    ②第二步:由根視圖DecorView經過一層層的ViewGroup傳遞到某個子View,由該View負責消費該事件以及後續的事件。

    至於其餘的狀況,好比該View捕獲到事件後沒法消費拋給上層視圖或者某個ViewGroup捕獲到事件,則參考下圖:

 

 

5、something more

    除了分發、攔截和消費這三個方法外,還能夠在活動中爲View類設置監聽器接口:

    監聽觸摸事件:setOnTouchListener(),須重寫接口的onTouch()方法。

    監聽點擊事件:setOnClickListener(),須重寫接口的onClick()方法。

    監聽長按事件:setOnLongClickListener(),須重寫接口的onLongClick()方法

    觀察View類的源碼,有如下結論:

    ①View的onTouch()方法會先於onTouchEvent()方法執行,而且當前僅當onTouch()方法返回false時,纔會執行onTouchEvent()。

    ②只有當onTouchEvent()方法獲得調用,而且觸摸事件是ACTION_UP時,onClick()方法纔會被調用。這一點邏輯上也很是容易理解,由於當用戶手指按下屏幕,只有當他手指離開屏幕觸發事件ACTION_UP後纔算是一個點擊事件。也就是說,當一個View肯定捕獲觸摸事件時,onTouch()方法會介於分發方法和消費方法之間執行,而且只有當其返回false時,後續的消費方法onTouchEvent()才能執行。而只有onTouchEvent()方法成功執行返回true,才能表示觸摸事件被正確處理,若是是ACTION_UP被正確處理,那麼就會調用onClick()方法。

    ③這三個監聽方法的執行順序是:onTouch()方法→onLongClick()→onClick() 緣由:當用戶按下手指後,先執行觸摸監聽方法;若是用戶按下時間超過一個閾值尚未鬆手,會執行長按監聽方法;若是用戶最後鬆開手指,最後執行點擊監聽方法。而且這三個方法是後者依賴於前者的返回值!只有onClick()返回false,onLongClick()才能執行;只有onLongClick()返回false,onClick()才能執行。

.............................................................................................................................................................over

相關文章
相關標籤/搜索