Android事件分發(三)

到了這個環節,我們主要研究requestDisallowInterceptTouchEvent的使用。我們之前對這個方法的通俗解釋是“請求父親不要攔截給我的事件”。
首先,看一下官方源碼的解釋。

Called when a child does not want this parent and its ancestors to intercept touch events with {@linkViewGroup#onInterceptTouchEvent(MotionEvent)}.
當孩子不希望他的父親們通過onInterceptTouchEvent(MotionEvent)時調用該方法來攔截事件。注意:這裏是父親們哦

This parent should pass this call onto its parents. This parent must obey this request for the duration of the touch (that is, only clear the flag after this parent has received an up or a cancel
這個子孩子的父親應該將這個請求告知他的父親,該父親必須在touch事件中遵循該請求(即,當該父親收到up或者cancel事件時,纔會取消這個標誌位)

再看看ViewGroup的dispatchTouchEvent方法中的一段代碼

if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
當我們調用requestDisallowInterceptTouchEvent其實就是改變父類的
disallowIntercept這個標誌位,如果我們將其設置爲false,即請求不攔截
那麼父類的onInterceptTouchEvent方法根本不會被調用。
我的疑問
如果父類直接就把DOWN事件給攔截了,那麼這個方法還有意義嗎?我究竟在什麼時候纔可以請求呢?
1. 正常的實驗
首先,我們必須讓父親是可以攔截MOVE事件的。如果父親一旦攔截了事件,那麼這個手勢剩下的事件都不會被子類拿到了,那麼子類是無法請求不攔截的,除非下一個手勢的到來,disallowIntercept標誌位纔會被置位。
DOWN事件不攔截,在MOVE事件發生時請求父親攔截
Group_inner
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
System.out.println(“Group_inner嘗試截斷view的事件”);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return false;
case MotionEvent.ACTION_MOVE:
return true; //父親會攔截MOVE事件
case MotionEvent.ACTION_UP:
return false;
default:
}
return super.onInterceptTouchEvent(event);

    Event_view
    > @Override
public boolean dispatchTouchEvent(MotionEvent event) {
    System.out.println("view開始分發事件");
    //System.out.println("Y:"+event.getY());
    if (event.getY() > 100) {
        getParent().requestDisallowInterceptTouchEvent(false);//攔截
    }else{
        getParent().requestDisallowInterceptTouchEvent(true);//不攔截
    }
    return super.dispatchTouchEvent(event);
}
我們意圖很明顯,Group_inner不會攔截DOWN事件,Event_view必須獲得DOWN事件,然後請求父親不要攔截他的事件,即改變了disallowIntercept這個標誌位。然後來了MOVE事件,父類是希望攔截MOVE事件的,可惜他的標誌位已經被子類改變,無法執行onInterceptTouchEvent方法。但是一旦Y值超過了100,那麼子類重新請求父類攔截,後面的一切都順理成章了。
>06-24 11:29:48.536: I/System.out(765): eventView---DOWN事件,自己處理

06-24 11:29:48.666: I/System.out(765): eventView—MOVE事件,自己處理
06-24 11:29:48.686: I/System.out(765): eventView—MOVE事件,自己處理
06-24 11:29:48.756: I/System.out(765): Y:113.230774
06-24 11:29:48.766: I/System.out(765): group_inner分發事件
06-24 11:29:48.776: I/System.out(765): Group_inner攔截了MOVE事件
06-24 11:29:48.776: I/System.out(765): Y:123.29939
06-24 11:29:48.776: I/System.out(765): eventView—CANCEL事件,自己處理
06-24 11:29:48.786: I/System.out(765): group_inner—MOVE事件,自己處理
通過日誌,很多前面的結論再一次得到了驗證
父親攔截了MOVE事件後,該MOVE事件變成了一個CANCEL事件傳遞到了子類
後續的MOVE事件再也沒傳到父親的onInterceptTouchEvent方法中,而是直接到onTouchEvent中被處理了
2. 不正常的實驗
假如Group_inner直接攔截了DOWN事件呢?

06-24 11:49:12.315: I/System.out(810): Group_inner嘗試截斷view的事件
06-24 11:49:12.315: I/System.out(810): group_inner—DOWN事件,自己處理
06-24 11:49:12.405: I/System.out(810): group_inner—MOVE事件,自己處理
很明顯,子孩子根本沒有機會啊

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