Android Touch事件處理機制

當TouchEvent發生時,首先Activity將TouchEvent傳遞給最頂層的View, TouchEvent最先到達最頂層 view 的 dispatchTouchEvent ,然後由  dispatchTouchEvent 方法進行分發,如果dispatchTouchEvent返回true ,則交給這個view的onTouchEvent處理,如果dispatchTouchEvent返回 false ,則交給這個 view 的 interceptTouchEvent 方法來決定是否要攔截這個事件,如果 interceptTouchEvent 返回 true ,也就是攔截掉了,則交給它的 onTouchEvent 來處理,如果 interceptTouchEvent 返回 false ,那麼就傳遞給子 view ,由子 view 的 dispatchTouchEvent 再來開始這個事件的分發。如果事件傳遞到某一層的子 view 的 onTouchEvent 上了,這個方法返回了 false ,那麼這個事件會從這個 view 往上傳遞,都是 onTouchEvent 來接收。而如果傳遞到最上面的 onTouchEvent 也返回 false 的話,這個事件就會“消失”,而且接收不到下一次事件。 

onTouch方法: 是View的onTouchListener接口中定義的方法,當View綁定了onTouchListener後,當有touch事件觸發時,就會調用onTouch方法。

onTouchEvent方法: 是重寫了Activity中的方法。

Android的Touch事件處理分3個層面:Activity層,ViewGroup層,View層
Touch事件處理的幾條基本原則:
1.如果在某個層級沒有處理ACTION_DOWN,那麼該層就再也收不到後續的Touch事件了,直到下ACTION_DOWN事件
  說明:
    a.某個層級沒有處理某個事件指的是它以及它的子View都沒有處理該事件
    b.這條規則不適用於Activity層(它是頂層),他們可以收到每一個Touch事件。
    c.沒有處理ACTION_MOVE這類事件,不會有任何影響

2.如果ACTION_DOWN事件發生在某個View的範圍之內,則後續的ACTION_MOVE,ACTION_UP和ACTION_CANCEL等事件都將發往該View,即使事件已經出界了
3.第一根按下的手指觸發ACTION_DOWN事件,之後按下的手指觸發ACTION_POINTER_DOWN事件,中間起來的手指觸發ACTION_POINTER_UP事件,最後起來的手指觸發ACTION_UP事件(即使它不是觸發ACTION_DOWN事件的那根手指)。
4.pointer id可以跟蹤手指,從按下的那個時刻起pointer id生效,直至起來的那一刻失效,這之間維持不變。
5.如果一個ACTION_DOWN事件被付View攔截了,則任何子View不會再收到任何Touch事件了(這符合第一點要求)
6.如果一個非ACTION_DOWN事件被父Vew攔截了,則那些上次處理了ACTION_DOWN事件的子View會收到一個ACTION_CANCEL事件,之後不會再收到任何Touch事件了,即使父View不再攔截後續的Touch事件。
7.如果父View決定處理Touch事件或者子View沒有處理Touch事件,則父View按照普通View的處理方式處理Touch事件,否則它根本不處理Touch事件(它只負責分發)
8.如果父View在onInterceptTouchEvent中攔截事件,則onInterceptTouchEvent中不會再收到Touch事件了,事件被直接交給它自己處理


總結:

Android事件觸發流程:

-------------------------------------------------------------------

首先觸發ACTIVITY的dispatchTouchEvent

然後觸發ACTIVITY的onUserInteraction

然後觸發LAYOUT的dispatchTouchEvent

然後觸發LAYOUT的onInterceptTouchEvent

-------------------------------------------------------------------

查看:http://hi.baidu.com/lck0502/blog/item/7eeb452a846ff196023bf654.html

=================================================================================================================

在ViewGroup(即上面Layout)情況特別分析:

針對由於觸摸(Touch)而觸發的事件。

Android的事件:onClick, onScroll, onFling等等,都是由許多個Touch組成的。其中Touch的第一個狀態肯定是ACTION_DOWN, 表示按下了屏幕。之後,touch將會有後續事件,可能是:

  • ACTION_MOVE //表示爲移動手勢

  • ACTION_UP //表示爲離開屏幕

  • ACTION_CANCEL //表示取消手勢,不會由用戶產生,而是由程序產生的

一個Action_DOWN, n個ACTION_MOVE, 1個ACTION_UP,就構成了Android中衆多的事件。

在Android中,有一類控件是中還可以包含其他的子控件,這類控件是繼承於ViewGroup類,例如:ListView, Gallery, GridView。

還有一類控件是不能再包含子控件,例如:TextView。

本文的主要討論對象就是ViewGroup類的控件嵌套時事件觸發情況。

對於ViewGroup類的控件,有一個很重要的方法,就是onInterceptTouchEvent(),用於處理事件並改變事件的傳遞方向,它的返回值是一個布爾值,決定了Touch事件是否要向它包含的子View繼續傳遞,這個方法是從父View向子View傳遞。

如果 return true時,會傳遞給當前控件的onTouchEvent(),而不在傳遞給子控件,這就是所謂的Intercept(截斷)。

如果return false;(默認是false)那麼表示該方法並未完全處理,

這樣才能把事件傳給View裏的onTouchEvent.

ViewGroup裏的onTouchEvent默認值是false。

View裏的onTouchEvent返回默認值是true.這樣才能執行多次touch事件

由於onInterceptTouchEvent()的機制比較複雜,總結一下,基本的規則是:

1.       down事件首先會傳遞到onInterceptTouchEvent()方法

2.       如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之後return false,那麼後續的move, up等事件將繼續會先傳遞給該ViewGroup,之後才和down事件一樣傳遞給最終的目標view的onTouchEvent()處理。

3.       如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之後return true,那麼後續的move, up等事件將不再傳遞給onInterceptTouchEvent(),而是和down事件一樣傳遞給該ViewGroup的onTouchEvent()處理,注意,目標view將接收不到任何事件。

4.       如果最終需要處理事件的view的onTouchEvent()返回了false,那麼該事件將被傳遞至其上一層次的view的onTouchEvent()處理。(尼瑪,return false時,向父View傳遞啊)

5.       如果最終需要處理事件的view 的onTouchEvent()返回了true,那麼後續事件將可以繼續傳遞給該view的onTouchEvent()處理。


而方法onTouchEvent(),用於接收事件並處理,它的返回值也是一個布爾值,決定了事件及後續事件是否繼續向上傳遞,這個方法是從子View向父View傳遞。

Touch事件在 onInterceptTouchEvent()和onTouchEvent以及各個childView間的傳遞機制完全取決於onInterceptTouchEvent()和onTouchEvent()的返回值。返回值爲true表示事件被正確接收和處理了,返回值爲false表示事件沒有被處理,將繼續傳遞下去(只是傳遞方向不一樣,onInterceptTouchEvent()向子View傳,而onTouchEvent()向父View傳)

具體情況如下:

ACTION_DOWN事件會傳到某個ViewGroup類的onInterceptTouchEvent,如果返回false,則DOWN事件繼續向子ViewGroup類的onInterceptTouchEvent傳遞,如果子View不是ViewGroup類的控件,則傳遞給它的onTouchEvent。

如果onInterceptTouchEvent返回了true,則DOWN事件傳遞給它的onTouchEvent,不再繼續傳遞,並且之後的後續事件也都傳遞給它的onTouchEvent。

如果某View的onTouchEvent返回了false,則DOWN事件繼續向其父ViewGroup類的onTouchEvent傳遞;如果返回了true,則後續事件會直接傳遞給其onTouchEvent繼續處理。(後續事件只會傳遞給對於必要事件ACTION_DOWN返回了true的onTouchEvent)

總結一下就是:onInterceptTouchEvent可以接受到所有的Touch事件,而onTouchEvent則不一定。

以上摘錄自:http://www.cnblogs.com/kingcent/archive/2011/03/08/1977059.html



發佈了114 篇原創文章 · 獲贊 35 · 訪問量 91萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章