Android事件傳遞機制【Touch事件】

Android中提供了ViewGroup、View、Activity三個等級的Touch事件處理。也就是說,這三個地方都有事件回調方法。

測試DEMO視圖結構:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<com .orgcent.eventtest.EventLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#032d3d"
   android:orientation="vertical" >
    <com .orgcent.eventtest.EventTextView
       android:id="@+id/tvEvent"
       android:layout_width="fill_parent"
       android:layout_height="100dp"
       android:gravity="center"
       android:textColor="@android:color/black"
       android:background="@android:color/white"
       android:text="Activity - ViewGroup - View Event http://orgcent.com dispatch Test"/>
</com>

至於三者之間的執行順序,將在下面詳細闡述:

整體上看,事件傳遞順序爲ViewGroup::onInterceptTouchEvent() –> ViewGroup或View的onTouchEvent() –> Activity::onTouchEvent()

由於上面每個事件回調方法的返回值不同,導致事件本身及順序發生微妙變化。下面以返回值爲主線來詳細闡述:

需要注意以下兩點:
1、onInterceptTouchEvent()返回true,那麼這個方法只會攔截動作ACTION_DOWN。
2、onInterceptTouchEvent()負責事件分發(事件傳遞方向),onTouchEvent()負責事件處理(消費)。

1、ViewGroup的onInterceptTouchEvent()
返回false:

默認實現方式。事件(按下、移動、擡起等)將直接傳遞給目標view(用戶觸摸的view)。
在ViewGroup觸發,調用ViewGroup::onTouchEvent(),在View觸發,調用View::onTouchEvent()。

androi-touch-event-1
PS:這裏發現ViewGroup::onTouchEvent()也被調用了,原因是View::onTouchEvent()沒有處理該事件(返回false),事件將交給父容器處理。

返回true:
表示ViewGroup將攔截子View的Touch事件。事件會直接傳遞到ViewGroup::onTouchEvent()處理。
也就是說,事件後面的移動、擡起動作不會經過onInterceptTouchEvent(),而是直接傳到onTouchEvent()。

androi-touch-event-2

2、ViewGroup/View的onTouchEvent()
返回true:

表示事件按下動作被處理,意味着事件的移動、擡起等後續動作將會傳到此方法。
如果是View處理,那麼ViewGroup的onTouchEvent()將不會獲得該事件。

androi-touch-event-3
PS:只要onInterceptTouchEvent()返回false,而且目標控件View::onTouchEvent()返回true,那麼事件的每一個動作(按下、移動、擡起等)會都會首先傳遞到onInterceptTouchEvent()中。

如果是ViewGroup處理,那麼Activity不會獲得事件。
androi-touch-event-4

返回false:
表示View或ViewGroup不處理事件,系統將把事件傳遞給其父級處理。

如果View返回false,那麼將由其父容器ViewGroup處理。如果ViewGroup不處理,最終將交給Activity來處理。
androi-touch-event-5

如果ViewGroup返回false,將交給最後一級Activity來處理。
androi-touch-event-6

3、Activity的onTouchEvent()
這個方法是事件最後被處理的地方。如果不處理,系統將拋棄這個事件。暫時沒有發現這個方法的返回值對程序有什麼意義。也許返回true能告訴系統事件被處理了。

小提示:
不要直接在程序中調用事件的回調方法。可以使用dispatchTouchEvent(MotionEvent)來分發事件。

DEMO:android_event_test.zip (56.8 KB, 46 次)

轉載請註明地址: http://orgcent.com/android-touch-event-mechanism/ | 蘿蔔白菜的博客


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章