zoukankan      html  css  js  c++  java
  • 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;
        } 
    }
    复制代码

    有不明白的下载源码运行看看结果

    源码下载:https://files.cnblogs.com/xiaoQLu/MotionEventTest.rar

  • 相关阅读:
    AS将一个项目导入到另一个项目中
    Android Studio出现:Cause: unable to find valid certification path to requested target
    小米手机Toast带app名称
    PopupWindow 点击外部区域无法关闭的问题
    EditText inputType类型整理
    Fragment通过接口回调向父Activity传值
    Android selector一些坑
    Installation failed with message Failed to commit install session 634765663 with command cmd package
    旷视上海研究院机器人方向招聘
    语义SLAM的数据关联和语义定位(四)多目标测量概率模型
  • 原文地址:https://www.cnblogs.com/LiesSu/p/3899484.html
Copyright © 2011-2022 走看看