1. 程式人生 > >Android 事件分發機制詳解(1)

Android 事件分發機制詳解(1)

Android事件分發機制詳解(一)

所謂Android事件分發機制,其實也就是View的事件分發機制,在介紹事件的傳遞規則之前,首先我們要明白這裡需要分析的物件MotionEvent。

MotionEvent類

在手指接觸屏幕後所產生的事件封裝成了MotionEvent類,典型的事件型別有如下幾種:

  • ACTION_DOWN:手機剛接觸螢幕
  • ACTION_MOVE:手指在螢幕上移動
  • ACTION_UP:手指從螢幕上鬆開的一瞬間
  • ACTION_CANCEL:結束事件(非人為)

正常情況下,一次手指觸控式螢幕幕的行為會觸發一系列事件,也就是我們說的事件序列,考慮如下幾種情況:

  • 點選行為:ACTION_DOWN -> ACTION_UP
  • 滑動行為:ACTION_DOWN->ACTION_MOVE->…..->ACTION_MOVE->AVTION_UP

同一個事件序列是指從手指接觸螢幕起得那一刻起,到手指離開螢幕那一刻結束,在這個過程中所產生的一系列事件,這個事件序列以down事件開始,中間含有數量不定的move事件,最終以up事件結束。

當MotionEvent產生後,系統要把這個事件傳遞給一個具體的View,而這個傳遞的過程也就是我們所說的事件分發。

事件分發的主要方法

  • public boolean dispatchTouchEvent(MotionEvent ev):用來進行事件的分發。如果事件能夠傳遞給當前View,那麼此方法一定會呼叫,返回值表示是否消耗當前事件。
  • public boolean onInterceptTouchEvent(MotionEvent ev):在dispatchTouchEvent方法中呼叫,用來進行事件的攔截,只有ViewGroup有這個方法,返回值表示是否攔截。若當前View攔截了某個事件,那麼在同一個事件序列中,此方法不會被再次呼叫。
  • public boolean onTouchEvent(MotionEvent ev):在dispatchTouchEvent方法中呼叫,用來進行事件的處理,返回值表示是否消耗當前事件。如果不消耗,則在同一個事件序列中,當前View無法再次接收到事件。

事件分發機制

這裡我們用一個例項來說明事件分發機制:

圖1

如圖,當用戶點選btn所在的區域時,android會怎麼處理這個點選事件呢?

當一個事件產生後,它的傳遞過程遵循如下順序:Activity->Window->View,即事件總是先傳遞給Activity,Acitivity再傳遞給Window,最後Window再傳遞給頂級View(ViewGroup繼承於View,所以可是一個View)。頂級View接收到事件以後,再按照事件分發機制去分發事件。

在上圖場景中,Window會將事件傳遞給LL_1,這時LL_1的dispatchTouchEvent方法就會被呼叫,如果該方法內的onInterceptTouchEvent方法返回true,則表示LL_1要攔截此次事件,該事件會交由LL_1處理,LL_1的OnTouchEvent方法會被呼叫。若onInterceptTouchEvent方法返回false,表示LL_1不攔截此次事件,該事件會繼續向它的子元素傳遞。

LL_2接收到該事件時,會做和LL_1一樣的事情,而當btn接收到該事件時,同樣也會呼叫dispatchTouchEvent方法,而由於btn是一個View,沒有OnInterceptTouchEvent方法,onTouchEvent方法會直接被執行,若onTouchEvent方法返回false,則表示該事件沒有被消耗,那麼它的父元素LL_2的onTouchEvent方法則會被呼叫,若LL_2的onTouchEvent方法依舊返回false,則呼叫LL_2父元素即LL_1的onTouchEvent方法,以此類推,若最終所有元素都不處理這個事件,那麼這個事件最終會傳遞給Activity處理,即Activity的onTouchEvent方法會被呼叫。

下面是圖解:
時間分發機制圖解

需要注意的是:
1)正常情況下,一個事件序列只能被一個View攔截且消耗,因為一旦一個元素攔截了某次事件,那麼同一個時間序列內的所有事件都會直接交給它處理,因此同一個事件序列中的時間不能分別由兩個View同時處理,但是通過特殊手段可以做到,例如一個View將本該自己處理的事情通過onTouchEvent強行傳遞給其他View處理。
2)某個ViewGroup一旦決定攔截,那麼這一個事件序列都只能由它來處理(如果事件序列能夠傳遞給它的話),並且它的onInterceptTouchEvent不會再被呼叫。
3)某個View一旦開始處理事件,如果它不消耗ACTION_DOWN事件(onTouchEvent返回了false),那麼同一事件序列的其他事件都不會交給它來處理,並且事件將重新交個它的父元素來處理,即呼叫父元素的onTouchEvent來處理。
4)如果View不消耗除了ACTION_DOWN以外的其他事件,那麼這個點選事件會消失,此時父元素的onTouchEvent方法不會被呼叫,最終這些消失的點選事件會傳遞給Activity處理。
5)ViewGroup預設不攔截任何事件。
6)View的onTouchEvent預設都會消耗事件(返回true),除非它是不可點選的(clickable和longclickable同時為false)。
7)View的enable屬性不影響onTouchEvent的預設返回值。
8)事件傳遞過程是由外向內的,即事件總是傳遞給父元素,再由父元素分發給子元素,通過requestDisallowInterceptTouchEvent方法可以再子元素中干預父元素的事件分發過程,但是ACTION_DOWN除外。

OnTouchListener、OnClick、onTouchEvent之間的關係

當一個View需要處理事件時,如果它設定了OnTouchListener,那麼OnTouchListener中的onTouch方法會被回撥。這時事件如何處理得看onTouch的返回值,若返回false,則當前View的onTouchEvent方法會被呼叫;如果返回true,那麼onTouchEvent方法將不會被呼叫。而在onTouchEvent方法中,如果當前View設定的有OnClickListener,那麼它的onClick方法會被呼叫;由此可見三者之間的優先順序關係為:OnTouchListener > onTouchEvent > OnClick。

相關推薦

Android 事件分發機制1

Android事件分發機制詳解(一) 所謂Android事件分發機制,其實也就是View的事件分發機制,在介紹事件的傳遞規則之前,首先我們要明白這裡需要分析的物件MotionEvent。 MotionEvent類 在手指接觸屏幕後所產生的事件封裝成了Mo

View的事件體系之三 android事件分發機制

  接著上一篇來分析事件分發機制,在看了各位大牛的關於事件分發機制的分析後茅塞頓開,之前看過好幾遍郭霖,弘揚以及玉剛大神關於事件體系的講解,一直看不懂,比較模糊,最近複習時,看到一篇博文,寫的相當精彩,看完後,再回看各位大神的博文,收穫頗豐,記錄一下自己的理解和

Android事件分發機制

概述   眾所周知,Android事件分發機制是Android知識體系中的重點也是難點。說白了,要學好Android,事件分發機制是無論如何也繞不過去的。   也許你會問,Android事件分發機制那麼重要,我怎麼沒用過呢?   當你被不同item的側滑刪除衝突

android 事件分發機制

摘要: 整個事件分發就類似於分發任務是一樣的 老大分配任務給老二 、老二分配任務給老三 如果老三完成了,這個任務就結束了,如果老三沒有完成則會將任務

Android事件傳遞機制巢狀自定義View示例

一、概述   自定義View如果嵌套了自定義View,可能簡單寫一個onTouchEvent處理事件已經不能解決你的需要。簡單舉個例子: 你自定義了一個容器View,簡稱為父View,在這裡監聽點選事件,做事情A,監聽滑動做事情B 然後你又自定了一個View,放入該容器

Hadoop編碼解碼【壓縮壓縮】機制1

編碼/解碼器一旦找到,就會被用來去掉檔名字尾生成輸出檔名(通過CompressionCodecFactory的靜態方法removeSuffix()來實現)。這樣,如下呼叫程式便把一個名為file.gz的檔案解壓縮為file檔案: % hadoop FileDecompressor file.gz Comp

Android開發——事件分發機制---微信魚蝦蟹源碼搭建

lai reset 微信 影響 ren 事件分發機制 lis forum hlist 轉載請註明出處:http://h5.hxforum.com深入學習事件分發機制,是為了解決在Android開發中遇到的滑動沖突問題做準備。事件分發機制描述了用戶的手勢一系列事件是如何被An

Android開發——事件分發機制

0. 前言深入學習事件分發機制,是為了解決在Android開發中遇到的滑動衝突問題做準備。事件分發機制描述了使用者的手勢一系列事件是如何被Android系統傳遞並消費的。首先對事件分發機制進行概述:如果

安卓自定義View進階-事件分發機制

Android 事件分發機制詳解,在上一篇文章 事件分發機制原理 中簡要分析了一下事件分發機制的原理,原理是十分簡單的,一句話就能總結:責任鏈模式,事件層層傳遞,直到被消費。 雖然原理簡單,但是隨著 Android 不斷的發展,實際運用場景也越來越複雜,所以想要徹底玩轉事件分發機制還

FTS資料庫優化Android原理與應用1

在Android的官方開發文件上,有建議在使用文字類的資料庫全文搜尋(full-text search)時,使用FTS優化查詢速度。有關FTS的介紹文章不多,本文調研整理一下有關知識,供在Android上使用FTS之前參考。 1.什麼是FTS? FTS,即full te

Js事件1事件型別及幾種新增事件處理程式的方法

js中的事件 早期的事件流的兩種解決方案: 1.IE:事件冒泡流 即事件開始時由最具體的元素(DOM中層次最深的那個節點)接收,然後逐級向上傳播到較為不具體的節點(文件)–自下向上。 所有現代的瀏覽器都支援事件冒泡。 2.Netscape Co

Android進階——效能優化之佈局渲染原理和底層機制

引言 UI 全稱User Interaction,我第一次聽到這個名詞是在大學的時候,當時候上人機互動課,我們教授說他認為iPhone的i 就是代表Interaction的意思,暫且不必爭辯是非。回到我們軟體開發中來,UI是使用者感知與互動的第一且唯一的途徑,

MongoDB執行計劃分析1

mongo smu pre als comm 計劃 -- {} direct 正文 queryPlanner queryPlanner是現版本explain的默認模式,queryPlanner模式下並不會去真正進行query語句查詢,而是針對query語句進行執行計劃分析並

JVM類加載機制JVM類加載過程

進行 虛擬機啟動 類加載的時機 bsp 參與 tro ext 環境 java代碼 首先Throws(拋出)幾個自己學習過程中一直疑惑的問題: 1、什麽是類加載?什麽時候進行類加載? 2、什麽是類初始化?什麽時候進行類初始化? 3、什麽時候會為變量分配內存? 4、什麽時候會為

Java的反射機制

pbc spa 詳解 uno face target lan tor cin 8n72q傅釁8戰sig叢http://www.docin.com/app/user/userinfo?userid=179185461 8u炊3F7LB椒1http://huiyi.docin.

跟開濤學SpringMVC4.1:Controller接口控制器1

詳解 shu fix gmv 控制器 input abstract pre pdf http://www.importnew.com/19397.html http://blog.csdn.net/u014607184/article/details/5207453

指標1-- 軌道線指標ENE

本質 平均值 width 簡單 公式 方向 重新 alt 改變 軌道線指標(ENE): 1、定義:軌道線(ENE)由上軌線(UPPER)和下軌線(LOWER)及中軌線(ENE)組成,軌道線的優勢在於其不僅具有趨勢軌道的研判分析作用,也可以敏銳的覺察股價運行過程中方向的改

JAVA線程池原理1

err 最大 RKE private queue 分享 ren ++ ant 線程池的優點 1、線程是稀缺資源,使用線程池可以減少創建和銷毀線程的次數,每個工作線程都可以重復使用。 2、可以根據系統的承受能力,調整線程池中工作線程的數量,防止因為消耗過多內存導致服務器崩潰。

Android EventBus3.x 使用

led AC target 分解 感覺 div activit .org android事 ?(^∇^*) 五一假期在家無事,新項目中用的是RxJava2+EventBus感覺還不錯,趁這閑暇總結下EventBus 一、概要簡述   EventBus

Spring Boot中使用MyBatis註解配置1

sql type .org 實體 sch 整合 PE 匯總 同傳 之前在Spring Boot中整合MyBatis時,采用了註解的配置方式,相信很多人還是比較喜歡這種優雅的方式的,也收到不少讀者朋友的反饋和問題,主要集中於針對各種場景下註解如何使用,下面就對幾種常見的情況舉