天天看點

onTouch事件傳遞前言1.基本知識2. 傳遞規律3.傳遞路線4.要點5.總結6.思維導圖熱門文章

前言

在我們的項目中,遇到比較複雜布局的時候,最常見的就是布局嵌套和自定義控件,那麼滑動沖突與點選沖突你一定是遇到過的,解決的方法有很多,但是總的來說都是對onTouch事件傳遞做處理.那麼我們就來了解一下onTouch事件到底是怎麼傳遞的

1.基本知識

我們先看看相關的幾個方法

(View是沒有onInterceptTouchEvent方法的)

ViewGroup

  • 1. dispatchTouchEvent(分發touch事件)
  • 2. onInterceptTouchEvent(攔截touch事件)
  • 3. onTouchEvent(消費事件)

View

  • 1. dispatchTouchEvent(分發touch事件)
  • 2. onTouchEvent(消費事件)

一個事件首先會由dispatchTouchEvent決定怎麼配置設定,接着由onInterceptTouchEvent決定是否攔截,最後由onTouchEvent決定怎麼消費

一般來說我們會重寫onInterceptTouchEvent和onTouchEvent方法來改變事件的傳遞,但是不會去重寫dispatchTouchEvent方法

下面為了更好的描述,有些地方就用簡稱描述了

  • dispatchTouchEvent : 配置設定
  • onInterceptTouchEvent : 攔截

2. 傳遞規律

(1)基本傳遞方向

首先我們需要知道onTouch事件傳遞的基本傳遞方向,onTouch事件的傳遞方向大概是從父控件傳遞到子控件,然後再從子控件傳回父控件,這個過程中一旦事件被消費了,那麼事件就不會繼續傳遞了

(2)攔截

onInterceptTouchEvent方法會有一個傳回值,如果你傳回的是false,表示不攔截,那麼事件就會先往子控件傳遞,如果你傳回的是true,表示攔截,那麼事件不會往下傳遞了

(3)消費

可以消費事件的地方有兩個:

  • OnTouchListener: 通過setOnTouchListener設定的OnTouchListener裡面的onTouch方法
  • onTouchEvent: 控件本身的onTouchEvent方法

這兩個方法都有傳回值,如果你傳回的是true,代表事件被消費了,如果你傳回的是false,那麼就算你在方法裡做了很多事,也不算消費

當OnTouchListener存在的時候,會先擷取到事件,如果不消費的話才會傳到onTouchEvent

OnTouchListener雖然優先于onTouchEvent,但都屬于同一層的消費,在這裡我們就不分開來描述了,統一描述為自己消費

(OnTouchListener > onTouchEvent)

(4)一組事件

move和up事件往往是和dowm事件相關聯的,為了簡化描述,我們這裡就把down,move,up同一稱為一組事件(下一次down事件之後的算下一組)

(5)控件

這裡指的所有控件都是在onTouch事件的點選範圍内,如果不在這個點選範圍内的控件,是不會參與事件傳遞的

3.傳遞路線

一個控件擷取到事件時,首先會走dispatchTouchEvent,才會走onInterceptTouchEvent和onTouchEvent,一般我們都不會去重寫dispatchTouchEvent方法(研究源碼的需要重點研究這個方法),是以接下來的傳遞路線就跳過dispatchTouchEvent這個方法了

這個例子裡面隻有一個ViewGroup,ViewGroup裡面有隻有一個View

onTouch事件傳遞前言1.基本知識2. 傳遞規律3.傳遞路線4.要點5.總結6.思維導圖熱門文章

4.要點

(1)攔截

①如果ViewGroup在onInterceptTouchEvent裡面攔截了down事件,那麼這一組事件都不會再進入onInterceptTouchEvent方法裡面了,也不會配置設定到View裡面了

(2)消費

①如果ViewGroup消費了down事件,那麼這一組事件不會進入到onInterceptTouchEvent裡面了,更不會配置設定到View裡面了,而是直接從dispatchTouchEvent方法走到自己消費的方法裡

(3)多個View

如果ViewGroup有多個View,那麼會從最上面的view周遊,如果有view消費了down事件,那麼就不會繼續周遊了,而且這一組事件也會直接進入這個view

(還會走ViewGroup的配置設定和攔截方法)

5.總結

onTouch事件的傳遞有很多可能的路線,這裡就不貼出筆者當初研究的DEMO代碼了,免得看得頭暈.你隻要知道幾個主要的原則和規律,再複雜的情況你也能夠知道事件會怎麼傳遞,這裡就再次總結一下

(1)一個ViewGroup有三種方法,配置設定,攔截,消費

  • 配置設定: dispatchTouchEvent
  • 攔截: onInterceptTouchEvent
  • 消費: OnTouchListener和onTouchEvent (優先走OnTouchListener的onTouch)

(View的話沒有攔截)

(2)首先事件會從父控件開始,逐級往下傳遞

(2)事件經過某個控件的時候,會先走配置設定,再走攔截,如果不攔截又會接着往下配置設定

(3)事件從上往下配置設定時,要麼是走到某一層被攔截了,要麼是走到最底層了才會停止向下配置設定

(4)一旦停止向下傳遞,就要開始考慮消費的事了

(5)從停止傳遞的那一層開始,詢問是否要消費事件,如果自己不消費,那麼逐級往上詢問

(6)一旦某層把事件消費了,那麼就不再向上詢問,事件傳遞就到此結束了

onTouch事件傳遞前言1.基本知識2. 傳遞規律3.傳遞路線4.要點5.總結6.思維導圖熱門文章

6.思維導圖

筆者當初第一次研究的時候做了一個DEMO,并把傳遞的過程用思維導圖詳細的記錄了下來,有興趣的朋友可以去下載下傳看看,免費的哦,不過還是建議有時間的朋友能夠自己寫demo測試一下,這樣才能更好的了解.

思維導圖

http://download.csdn.net/download/yulyu/9763226

熱門文章

  • 程序間通信–AIDL
  • 序列化–Serializable與Parcelable
  • 如何解決記憶體溢出以及記憶體洩漏
  • Okhttputils終極封裝
  • FaceBook推出的調試神器
  • Android代碼優化工具
  • Glide-入門教程
  • Glide-圖檔預處理(圓角,高斯模糊等)
  • Glide-圖檔的壓縮
  • Glide-記憶體緩存與磁盤緩存
  • Glide-自定義緩存