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

ACTION_CANCEL事件和事件回传

时间: 2024-07-30 01:28:59

ACTION_CANCEL事件和事件回传的相关文章

浅谈JavaScript的事件(事件流)

 事件流描述的是从页面中接收事件的顺序.IE的事件流失事件冒泡,而Netspace的事件流失事件捕获. 事件冒泡 IE的事件流叫事件冒泡,即事件开始时,由具体的元素(文档中嵌套层次最深的节点)接收,然后向上传播到不具体的节点. 1 <html onclick="console.log('html')"> 2 <head> 3 <meta charset="UTF-8"> 4 <title></title>

JavaScript-4.5 事件大全,事件监听---ShinePans

绑定事件 <input type="bubtton" onclick="javascript:alert('I am clicked');"> 处理事件 <script language="JavaScript" for="对象" event="事件"> ... (事件处理代码) ... </script> 鼠标事件举例 <script language="

DDD领域事件与事件总线源码下载

最近在看领域事件的文章.看到了“张占岭”的<DDD~领域事件与事件总线> 原文地址:http://www.cnblogs.com/lori/p/3476703.html 遗憾的是没有提供下载,把文中的代码复制下来但发现不完整.于是决定自己补全代码. 说明:本来只是打算做一次性的测试项目所以没有命名的.其中用XML初始化的代码也被注释了. 下载地址: http://pan.baidu.com/s/1c0DD5eS 梦回周公

IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素

IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素. attachEvent(type,listener); listener函数中的this不是指向执行当前事件的dom而是window切记,感觉这一点IE做的太奇怪了!

三言两语之js事件、事件流以及target、currentTarget、this那些事

厉害了我的哥——你是如此简单我却将你给遗忘   放假前再看某文档,里边提到两个我既熟悉又陌生的概念target.currentTarget,说他熟悉我曾经看到过这两个事件对象的异同处,说他陌生吧?很不巧.正要运用了,吾才发现吾压根就没记住...其实要讲清楚target.currentTarget,我们就不得不说一下事件流这个概念,而要言明事件流,我们也要晓得一下神马是事件以及一些周边生态概念,这三个概念是必须放在一块说,我们才能对能对这部分的知识有很好的理解滴,网上信息太零散,于是乎就有了这篇算

跨浏览器的事件处理程序——事件处理程序、事件对象差异

为了以跨浏览器的方式处理事件,不少开发人员会使用能够隔离浏览器差异的javascript库,本文从事件处理程序.事件对象差异出发,演示开发最适合的事件处理方法 基本名词解析: 事件 用户或浏览器自身执行的某种动作 事件流 从页面中接收事件的顺序,,IE的事件流指的是事件冒泡流,而Netscape Communicator的事件流是事件捕获流 事件冒泡 事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档) 事件捕获 不太具体的节点应该更早接收到事

直接事件与事件委托

最近学了JQ 刚刚在网上看了点关于直接事件与事件委托的知识: 比如:这样两段代码: $('ul li').on('click', function () { //todo }); $('ul').on('click','li', function () { //todo }) 他们的区别是什么呢?在JQuery的官网上有详细的解释,第一段是说把事件直接绑定在li上,如果有100个li,就相当于绑定了100次的li,而且只能绑定在文档中已存在的li上, 后续添加的li是绑定不上的,比如通过ajax

js事件流、事件处理程序/事件侦听器

1.事件流 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档). 事件捕获 事件捕获的思想是不太具体的节点应该更早的接收到事件,而最具体的节点应该在最后接收到节点.事件捕获的用意在于事件到达预定目标之前捕获它. DOM事件流 “DOM2级事件流”规定的事件流包括三个阶段:事件捕获阶段.处于目标阶段和冒泡阶段.首先发生的是事件捕获,为截获事件提供了机会.然后是实际的目标接收到

Atitit. &#160;Js 冒泡事件阻止&#160;事件捕获&#160;&#160;&#160;事件传递 &#160;事件代理

Atitit.  Js 冒泡事件阻止 事件捕获   事件传递  事件代理   1. 事件冒泡1 2. 事件捕获1 3. 同时支持了事件捕获阶段和事件冒泡阶段ddEventListener的第三个参数1 4. 事件代理3 5. 冒泡还是捕获?3 6. Js 冒泡事件阻止3 6.1. 返回false5 7. 事件冒泡 使处理函数有范围较大的触发面积,在“拖拽效果”脚本中是必须的5 8. refe6 8.1.1. 浅谈事件冒泡与事件捕获 - ac黄博客精选 - SegmentFault6   1. 事