android事件傳遞機制以及onInterceptTouchEvent()和OnTouchEvent()詳解三之ACTION_CANCEL事件和事件回傳


ANDROID事件傳遞機制以及ONINTERCEPTTOUCHEVENT()和ONTOUCHEVENT()詳解二之小秘與領導的故事

ANDROID事件傳遞機制以及ONINTERCEPTTOUCHEVENT()和ONTOUCHEVENT()總結

前兩篇博文講了onInterceptTouchEvent和OnTouchEvent的處理流程(沒有看的趕緊去補下)

聲明:原創作品,轉載請說明出處,來自 http://www.cnblogs.com/xiaoQLu/archive/2013/04/02/2994030.html

ACTION_CANCEL事件,官方文檔講的是當前手勢被釋放,你將不會接收到其他的事件,應該向ACTION_UP一樣對待它。

那到底什么情況會觸發這個事件呢?當 當前控件(子控件,兒子)收到前驅事件(ACTION_MOVE或者ACTION_MOVE)后,它的父控件(老爸)突然插手,截斷事件的傳遞,這時,當前控件就會收到ACTION_CANCEL,收到此事件后,不管子控件此時返回true或者false,都認為這一個動作已完成,不會再回傳到父控件的OnTouchEvent中處理,同時后續事件,會通過dispatchEvent方法直接傳送到父控件這里來處理。這和之前的結論有點相悖,之前說過如果子控件的OnTouchEvent返回false,表明事件未被處理,是回傳到父控件去處理的,這里糾正一下,只有ACTION_DOWN事件才可以被回傳,ACTION_MOVE和ACTION_UP事件會跟隨ACTION_DOWN事件,即ACTION_DOWN是哪個控件處理的,后續事件都傳遞到這里,不會上拋到父控件,ACTION_CANCEL也不能回傳。還有一點,觸摸區域的范圍問題,如果觸摸區域在子控件內,同時父控件沒有截斷事件傳遞,剛不管子控件是否攔截此事件,都會傳遞到子控件的OnTouchEvent中處理,可以看成一種責任吧,因為我點的就是你,你父親沒有攔截,說明他不想處理,那到你這里了,不管你攔不攔截,都得你來處理。

結論:ACTION_CANCEL事件是收到前驅事件后,后續事件被父控件攔截的情況下產生,onTouchEvent的事件回傳到父控件只會發生在ACTION_DOWN事件中

實例說明:在下面的實例中,LinearView1是父控件,LayoutView2是子控件,點擊區域是LayoutView2,可以看到父控件的onInterceptTouchEvent方法在ACTION_DOWN的時候沒有攔截事件,但是在ACTION_MOVE的時候突然插手,攔截掉事件,這時候,子控件就會收到ACTION_CANCEL。

 
        
public class LayoutView1 extends LinearLayout {

    private final String TAG = "LayoutView1";

    public LayoutView1(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.d(TAG, TAG);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            Log.d(TAG, "1:onInterceptTouchEvent action:ACTION_DOWN");
            //return true;
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d(TAG, "1:onInterceptTouchEvent action:ACTION_MOVE");
            return true;
            //break;
        case MotionEvent.ACTION_UP:
            Log.d(TAG, "1:onInterceptTouchEvent action:ACTION_UP");
            //return true;
            break;
        case MotionEvent.ACTION_CANCEL:
            Log.d(TAG, "1:onInterceptTouchEvent action:ACTION_CANCEL");
            break;
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            Log.d(TAG, "1:onTouchEvent action:ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d(TAG, "1:onTouchEvent action:ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.d(TAG, "1:onTouchEvent action:ACTION_UP");
            break;
        case MotionEvent.ACTION_CANCEL:
            Log.d(TAG, "1:onTouchEvent action:ACTION_CANCEL");
            break;
        }
        return true;
    }
}
public class LayoutView2 extends LinearLayout {
    private final String TAG = "LayoutView2";   

    public LayoutView2(Context context, AttributeSet attrs) {
       super(context, attrs);
       Log.d(TAG,TAG);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
       int action = ev.getAction();
       switch(action){
       case MotionEvent.ACTION_DOWN:
           Log.d(TAG,"2:onInterceptTouchEvent action:ACTION_DOWN");
           break;
           //return true;
       case MotionEvent.ACTION_MOVE:
           Log.d(TAG,"2:onInterceptTouchEvent action:ACTION_MOVE");
           break;
           //return true;
       case MotionEvent.ACTION_UP:
           Log.d(TAG,"2:onInterceptTouchEvent action:ACTION_UP");
           break;
       case MotionEvent.ACTION_CANCEL:
           Log.d(TAG,"2:onInterceptTouchEvent action:ACTION_CANCEL");
           break;
       }  
       return false;
}
 

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
       int action = ev.getAction();
       switch(action){
       case MotionEvent.ACTION_DOWN:
           Log.d(TAG,"2:onTouchEvent action:ACTION_DOWN");
           //return false;
           break;
       case MotionEvent.ACTION_MOVE:
           Log.d(TAG,"2:onTouchEvent action:ACTION_MOVE");
           return false;
           //break;
       case MotionEvent.ACTION_UP:
           Log.d(TAG,"2:onTouchEvent action:ACTION_UP");
           break;
       case MotionEvent.ACTION_CANCEL:
           Log.d(TAG,"2:onTouchEvent action:ACTION_CANCEL");
           break;
       }     
       return true;
    } 
}

有不明白的下載源碼運行看看結果

源碼下載:http://files.cnblogs.com/xiaoQLu/MotionEventTest.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM