首先,這篇文章僅僅針對於由於觸摸(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傳遞。
而方法onTouchEvent(),用於接收事件並處理,它的返回值也是一個布爾值,決定了事件及後續事件是否繼續向上傳遞,這個方法是從子View向父View傳遞。
touch事件在 onInterceptTouchEvent()和onTouchEvent以及各個childView間的傳遞機制完全取決於onInterceptTouchEvent()和onTouchEvent()的返回值。返回值爲true表示事件被正確接收和處理了,返回值爲false表示事件沒有被處理,將繼續傳遞下去。
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
MotionEvent事件在onInterceptTouchEvent()、onTouchEvent()中的傳遞順序
onInterceptTouchEvent()用於處理事件並改變事件的傳遞方向。處理事件這個不用說了,你在函數內部編寫代碼處理就可以了。而決定傳遞方向的是返回值,返回爲false時事件會傳遞給子控件的onInterceptTouchEvent();返回值爲true時事件會傳遞給當前控件的onTouchEvent(),而不在傳遞給子控件,這就是所謂的Intercept(截斷)。
onTouchEvent() 用於處理事件,返回值決定當前控件是否消費(consume)了這個事件。可能你要問是否消費了又區別嗎,反正我已經針對事件編寫了處理代碼?答案是有區別!比如ACTION_MOVE或者ACTION_UP發生的前提是一定曾經發生了ACTION_DOWN,如果你沒有消費ACTION_DOWN,那麼系統會認爲ACTION_DOWN沒有發生過,所以ACTION_MOVE或者ACTION_UP就不能被捕獲。
本文源地址:http://www.cnblogs.com/rocky_yi/archive/2011/01/21/1941522.html# ,轉載請註明出處!
<com.touchstudy.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.touchstudy.LayoutView2
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<com.touchstudy.MyTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv"
android:text="AB"
android:textSize="40sp"
android:textStyle="bold"
android:background="#FFFFFF"
android:textColor="#0000FF"/>
</com.touchstudy.LayoutView2>
</com.touchstudy.LayoutView1>
在沒有重寫onInterceptTouchEvent()和onTouchEvent()的情況下(他們的返回值都是false), 對上面這個佈局,MotionEvent事件的傳遞順序如下:
當某個控件的onInterceptTouchEvent()返回值爲true時,就會發生截斷,事件被傳到當前控件的onTouchEvent()。如我們將LayoutView2的onInterceptTouchEvent()返回值爲true,則傳遞流程變成:
如果我們同時將LayoutView2的onInterceptTouchEvent()和onTouchEvent()設置成true,那麼LayoutView2將消費被傳遞的事件,同時後續事件(如跟着ACTION_DOWN的ACTION_MOVE或者ACTION_UP)會直接傳給LayoutView2的onTouchEvent(),不傳給其他任何控件的任何函數。同時傳遞給子空間一個ACTION_CANCEL事件。傳遞流程變成(圖中沒有畫出ACTION_CANCEL事件):
附SDK給出的說明:
android中的事件類型分爲按鍵事件和屏幕觸摸事件,Touch事件是屏幕觸摸事件的基礎事件,
有必要對它進行深入的瞭解。 一個最簡單的屏幕觸摸動作觸發了一系列Touch事件:
ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
當屏幕中包含一個ViewGroup,而這個ViewGroup又包含一個子view,這個時候android系統如何
處理Touch事件呢?到底是ViewGroup來處理Touch事件,還是子view來處理Touch事件呢?我只能
很肯定的對你說不一定。呵呵,爲什麼呢?看看下面我的調查結果你就明白了。
android系統中的每個View的子類都具有下面三個和TouchEvent處理密切相關的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev)這個方法用來分發TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev)這個方法用來攔截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev)這個方法用來處理TouchEvent
當TouchEvent發生時,首先Activity將TouchEvent傳遞給最頂層的View,TouchEvent最先到達最頂層
view 的 dispatchTouchEvent ,然後由 dispatchTouchEvent 方法進行分發,
1、如果dispatchTouchEvent返回true,則交給這個view的onTouchEvent處理, 如果最終需要處理事件的view的onTouchEvent()返回了false,那麼該事件將被傳遞至其上一層次的view的onTouchEvent()處理。如果最終需要處理事件的view 的onTouchEvent()返回了true,那麼後續事件將可以繼續傳遞給該view的onTouchEvent()處理。
2、如果dispatchTouchEvent返回 false ,則交給這個view的interceptTouchEvent方法來決定是否
要攔截這個事件,如果 interceptTouchEvent 返回 true,也就是
3、若果interceptTouchEvent返回true,表示攔截掉了,則交給它的onTouchEvent 來處理,
4、如果 interceptTouchEvent 返回 false,那麼就傳遞給子view ,由子 view 的 d
ispatchTouchEvent 再來開始這個事件的分發。
5、如果事件傳遞到某一層的子 view 的onTouchEvent上了,這個方法返回了 false ,那麼這個事件
會從這個view 往上傳遞,都是 onTouchEvent來接收。
6、如果傳遞到最上面的 onTouchEvent 也返回 false的話,這個事件就會“消失”,而且接收
不到下一次事件。