事件之父View和子view的點擊事件的執行過程

 

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)  這個方法用來分發TouchEventhtml

2)public boolean onInterceptTouchEvent(MotionEvent ev)這個方法用來攔截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev)這個方法用來處理TouchEvent

當TouchEvent發生時,首先Activity將TouchEvent傳遞給最頂層的View, 
TouchEvent最早到達最頂層 view的 dispatchTouchEvent,而後由  dispatchTouchEvent方法進行分發,android

    若是dispatchTouchEvent返回true,則交給這個view的onTouchEvent處理,函數

    若是 dispatchTouchEvent返回 false,則交給這個 view的 interceptTouchEvent方法來決定是否要攔截這個事件,
        若是 interceptTouchEvent返回 true,也就是攔截掉了,則交給它的onTouchEvent來處理,
        若是 interceptTouchEvent返回 false,那麼就傳遞給子 view,由子 view 的dispatchTouchEvent再來開始這個事件的分發。佈局

若是事件傳遞到某一層的子 view的 onTouchEvent上了,這個方法返回了 false,那麼這個事件會從這個 view往上傳遞,都是onTouchEvent來接收。
若是事件傳遞到某一層的子view的onTouchEvent上了,這個方法返回true,那麼這個事件將不會向上傳遞了,由這個view攔截處理.
而若是傳遞到最上面的 onTouchEvent也返回 false的話,這個事件就會「消失」,並且接收不到下一次事件spa

 

onInterceptTouchEvent()用於處理事件並改變事件的傳遞方向。處理事件這個不用說了,你在函數內部編寫代碼處理就能夠了。而決定傳遞方向的是返回值,返回爲false時事件會傳遞給子控件的onInterceptTouchEvent();返回值爲true時事件會傳遞給當前控件的onTouchEvent(),而不在傳遞給子控件,這就是所謂的Intercept(截斷)。3d

onTouchEvent() 用於處理事件,返回值決定當前控件是否消費(consume)了這個事件。可能你要問是否消費了又區別嗎,反正我已經針對事件編寫了處理代碼?答案是有區別!好比ACTION_MOVE或者ACTION_UP發生的前提是必定曾經發生了ACTION_DOWN,若是你沒有消費ACTION_DOWN,那麼系統會認爲ACTION_DOWN沒有發生過,因此ACTION_MOVE或者ACTION_UP就不能被捕獲。code

本文源地址:http://www.cnblogs.com/rocky_yi/archive/2011/01/21/1941522.html# ,轉載請註明出處!xml

<?xml version="1.0" encoding="utf-8"?>
<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事件的傳遞順序以下:htm

 

當某個控件的onInterceptTouchEvent()返回值爲true時,就會發生截斷,事件被傳到當前控件的onTouchEvent()。如咱們將LayoutView2的onInterceptTouchEvent()返回值爲true,則傳遞流程變成:blog

 

 若是咱們同時將LayoutView2的onInterceptTouchEvent()和onTouchEvent()設置成true,那麼LayoutView2將消費被傳遞的事件,同時後續事件(如跟着ACTION_DOWN的ACTION_MOVE或者ACTION_UP)會直接傳給LayoutView2的onTouchEvent(),不傳給其餘任何控件的任何函數。同時傳遞給子空間一個ACTION_CANCEL事件。傳遞流程變成(圖中沒有畫出ACTION_CANCEL事件):

          

附SDK給出的說明:

相關文章
相關標籤/搜索