关闭

android的事件传递机制

84人阅读 评论(0) 收藏 举报

参考http://www.jianshu.com/p/2be492c1df96

  • onInterceptTouchEvent:

    • 事件拦截方法,只有在ViewGrop中存在,因为事件都会先传递到最顶层的parent,如果它没有做处理,该事件(dowm,up等事件)就会传递到下一层,下一层可能是view,也可能是viewgrop,如果是view则会进入它的onTouchEvent,如果是viewGroup则会进入它的onInterceptTouchEvent,以这样的规则往下传递。
    • 而且这个事件只能是一个一个处理:例如如果拦截了dowm事件,后面的move和up事件不会一起被拦截(就算底层的view处理了dowm事件,接下来的move事件还会传递到最顶层viewGroup的onInterceptTouchEvent中),这点与onTouchEvent不同!
  • onTouchEvent:

    • 只存在view(图中的C)中,一旦拦截了dowm事件,那么后面的move和up事件将不会传递到parent(图中的A和B)的onTouchEvent中!但是:后面的事件还是会先传递到A和B的onInterceptTouchEvent方法中的,如果此时A在它的onInterceptTouchEvent中对move事件进行了拦截,则C就不会再收到move事件(比如scroll事件就需要这样做,当滑动超出一定距离后就认为是滑动,需要拦截)。所以,在编码中,我们也常常在view的dispatchTouchEvent方法中通过getParent().requestDisallowInterceptTouchEvent(true);来确保父控件无法拦截对应的事件(从博文中看出一定是成功的),如下:
    getParent().requestDisallowInterceptTouchEvent(true);
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                if (如果父容器需要这个事件) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                }//否则的话 就交给自己本身view的onTouchEvent自动处理了
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }
    • (从博文中看出一定是成功的,所以这里应该没必要了)除了上面一个步骤,还需要确认父控件的onInterceptTouchEvent没有对事件进行拦截(父控件未拦截则不影响),否则子控件将无法收到该事件,如下:
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            return false;
        }
        return true;
    }
    • 如果最底层的view没有设置成clickable或者拦截这个事件,那么该事件将会继续往上传递到parent的onTouchEvent方法中。
  • 如图,事件的处理实际上经历了一下一上两个过程,下是指A->B的onInterceptTouchEvent,上是指C->B->A的onTouchEvent,当然,任意一步的方法中返回true,都能阻止它继续传播

  • 总结

    • 事件最先由ViewGroup的onInterceptTouchEvent往下一层一层传递到View的onTouchEvent,如果没有拦截,则再会往上一层一层传递到ViewGroup的onTouchEvent。所以可理解为onInterceptTouchEvent自上而下传递,onTouchEvent自下而上传递。
    • 一般如果某个View在onTouchEvent中拦截了dowm事件,如果没有必要,他的parent(ViewGroup)不会拦截接下来的事件。但是也有例外,这时候就会出现事件拦截(冲突),如子控件在onTouchEvent的dowm中返回了true,后面它想在move和up事件中也做一些处理,假设接下来它的parent在move事件中判断滑动大于某个值,它需要处理,并在onInterceptTouchEven的move中返回了true,此时这个事件将会变成一个CANCLE事件(文章中讲到的),view无法再处理了,而最后会传递到ViewGrop的onTouchEvent的move事件中。
    • 虽然上面ViewGroup可以中途拦截View的事件,但是在一些必要的情况下我们可以通过getParent().requestDisallowInterceptTouchEvent(true);来确保父控件无法拦截对应的事件。(这个是否一定成功吗?)
    • 其实dispatchTouchEvent才是整个事件处理的真正入口。如果我们需要监听整个Activity的事件并作出对应的处理(如监听点击非输入框的时候隐藏输入法),这样我们就可以重写Activity的事件分发方法dispatchTouchEvent,并判断当前获取焦点的view是否是EditText,不是则隐藏输入法。
    • 注意与前面的两个方法不同,dispatchTouchEvent返回false则表示拦截!!!
  • 事件传递的基本流程:

    • 事件都是从Activity.dispatchTouchEvent()开始传递;
    • 事件由父View传递给子View,ViewGroup可以通过onInterceptTouchEvent()方法对事件拦截,停止其向子view传递;
    • 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数;
    • 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来,也就是说ACTION_DOWN必须返回true,之后的事件才会传递进来;
    • OnTouchListener优先于onTouchEvent()对事件进行消费。也就是如果View设置了onTouchListener,会先执行OnTouchListener的onTouch方法。如果该方法返回true,表示消费了。不会执行onTouchEvent了,如果onTouch返回false,就会继续执行onTouchEvent
0
0
查看评论

android 事件机制图文详解-从源码角度分析彻底理解事件传递机制(上)

最近在看android开发艺术一书,因此对android 事件机制有更深层次的理解,在此记录一遍 探讨Android事件传递机制前,务必明确android的两大基础控件类型:View和ViewGroup。 View即普通的控件,没有子布局的,如Button、TextView. ViewGrou...
  • javazejian
  • javazejian
  • 2016-01-07 23:50
  • 1403

Android事件分发传递回传机制详解

如果想参与实际开发项目,若不理解事件分发回传机制的话,几乎等于“”摸黑抓鳅”,因为几乎每个项目都会出现滑动冲突问题;而要想解决滑动冲突问题,必须先了解甚至掌握事件分发传递机制。等到了解决滑动冲突时,至少没有一种“断层”的感觉。所以本专栏开篇先介绍事件机制,对安卓中的事件机制,做一个详细的介绍与分析。...
  • qq_32059827
  • qq_32059827
  • 2016-09-18 22:54
  • 1405

Android Touch事件传递机制全面解析(从WMS到View树)

转眼间近一年没更新博客了,工作一忙起来,很难有时间来写博客了,由于现在也在从事Android开发相关的工作,因此以后的博文也会更多地专注于这一块。 这篇文章准备从源码层面为大家带来Touch事件的传递机制,我这里分析的源码时Android4.4的。说到分析源码,光看肯定是不行的,一定要亲自去跟,并...
  • mmc_maodun
  • mmc_maodun
  • 2015-12-21 07:43
  • 8371

Android事件传递流程-伪代码

android 事件传递伪代码
  • u012227177
  • u012227177
  • 2017-04-24 19:36
  • 350

Android触摸屏事件派发机制详解与源码分析一(View篇)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!【工匠若水 http://blog.csdn.net/yanbober】Notice:阅读完该篇之后如果想继续深入阅读Android触摸屏事件派发机制详解与源码分析下一...
  • yanbober
  • yanbober
  • 2015-05-21 17:03
  • 51048

Android自定义view之事件传递机制

Android自定义view之事件传递机制 本文是自定义view入门的第二篇文章,主要讲解Android的事件分发流程,结合上一篇的绘制等流程,基本就可以掌握自定义view的核心内容。后续我会写一些实际的小例子,加深理解。
  • zuguorui
  • zuguorui
  • 2017-08-08 23:27
  • 333

Android点击事件传递机制详解

在讲正题之前我们讲一段有关任务传递的小故事,抛砖迎玉下: 话说一家软件公司,来一个任务,分派给了开发经理去完成: 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给了自己组员(程序员) 程序员:分派给了自己带的实习生。 实习生:好苦逼,无法分派,怎么办啊?只能...
  • RuingMan
  • RuingMan
  • 2016-05-16 15:45
  • 3358

Android-三张图搞定Touch事件传递机制

上图之前先讲下Android事件的基础知识:1.所有的Touch事件都封装到MotionEvent里面2.事件处理包括三种情况,分别为:传递—-dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费—-onTouchEvent()函数和OnTo...
  • Bond_zhe
  • Bond_zhe
  • 2016-08-13 18:27
  • 443

android 事件传递机制

总则: 1.onInterceptTouchEvent中有个Intercept,这是什么意思呢?她叫拦截,你大概知道她作用了吧,她就是你的亲亲小秘书,有什么事,先找秘书,秘书来决定这个事要不要你亲自处理,既然是秘书,是不是每个人都能有呢?当然不是,这个秘书只是viewgroup的,所以只有继承...
  • jks456
  • jks456
  • 2015-01-01 11:45
  • 488

【Android】事件传递机制

未完,待续
  • u010119170
  • u010119170
  • 2014-09-30 22:53
  • 329
    个人资料
    • 访问:9647次
    • 积分:438
    • 等级:
    • 排名:千里之外
    • 原创:36篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论