美文网首页我爱编程
Android Touch分发事件机制详解

Android Touch分发事件机制详解

作者: 从新开始学android | 来源:发表于2018-04-12 15:58 被阅读0次

    **********如果你理解起来比较困难,那你可以看看我的东西,一行一行读下去,至少理解肯定没问题*****

    这里主要是针对面试的速成知识点:

    原文:https://www.jianshu.com/p/38015afcdb58这里写的特别棒

    http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html

    事件分发主要是指对Touch事件的处理,何为Touch事件?

    就是我们常说的点击,触摸事件

    Touch事件的相关细节被封装成了一个事件对象:

    (发生触摸的位置、时间等)MotionEvent对象

    概念**********************************************************************************************

    ###一个定义:那么Touch事件的分发过程,就是指MotionEvent对象的传递,最终由谁来处理的过程;

    或者说事件(MotionEvent)传递到某个具体的View & 处理的整个过程

    事件传递的过程 = 分发过程

    ###四种类型:Touch事件类型:

    MotionEvent.ACTION_DOWN按下View(所有事件的开始)

    MotionEvent.ACTION_UP抬起View(与DOWN对应)

    MotionEvent.ACTION_MOVE滑动View

    MotionEvent.ACTION_CANCEL结束事件(非人为原因)

    一般手机触摸屏幕,再离开屏幕的过程,会出发一系列的Touch事件

    一般情况下,事件列都是以DOWN事件开始、UP事件结束,中间有无数的MOVE事件

    当一个事件(MotionEvent )产生后,系统需把这个事件传递给一个具体的 View去处理

    原理和过程分析:****************************************************************************

    ###主要三个对象:Activity,ViewGroup,View

    事件传递是在Activity,ViewGroup,View之间传递

    事件传递的顺序:Activity -> ViewGroup -> View

    即:1个点击事件发生后,事件先传到Activity、再传到ViewGroup、最终再传到 View

    ###主要三个方法:

    dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()

    三个对象,每个对象里都有dispatchTouchEvent()和onTouchEvent()方法

    ViewGroup里多了一个onInterceptTouchEvent()

    **********把以下的分析明白就OK了

    这里直接教你面试的时候怎么说:

    (1)Activity对点击事件的分发机制

    首先会先回掉Activity的dispatchTouchEvent方法,最终会交给ViewGroup的

    dispatchTouchEvent()处理。

    过程:————————————————————————————————————---------------------

    getWindow获取window类的对象,指向唯一的实现类Phonewindow对象,然后再调用他

    的superDispatchTouchEvent(ev)方法:

    里面调用到:

    mDecor.superDispatchTouchEvent(event);

    mDecor是(DecorView)的实例对象

    a. DecorView类是PhoneWindow类的一个内部类

     b. DecorView继承自FrameLayout,是所有界面的父类

     c. FrameLayout是ViewGroup的子类,故DecorView的间接父类 = ViewGroup

    // 调用父类的方法 = ViewGroup的dispatchTouchEvent()// 即 将事件传递到ViewGroup去处理

    —————————————————————————————————————————————

    ViewGroup的dispatchTouchEvent如果返回true,则不会再执行Activty的OnTouchEvent()方法;

    ViewGroup的dispatchTouchEvent如果返回false,则继续执行Activty的OnTouchEvent()方法;

    OnTouchEvent这个方法是在当Activty上面所有的View都没有接收处理这个事件的时候

    而且要求Activity的dispatchTouchEvent返回false super.OnTouchEvent,才会触发

    第一种情况:

    比如说你的Activity上什么都没有,但是你触摸了屏幕就一定会触发dispatchTouchEvent,如果没有View消费掉事件,那么会继续触发OnTouchEvent()事件

    第二种情况:

    如果Activty上有一个按钮,给按钮添加一个点击事件,那么这个按钮被点击时会触发Activity的dispatchTouchEvent方法,但是这个事件被Activity中的Button消费掉 了,那么Activity的OnTouchEvent就不会再继续执行了

    注意:

    如果Activty的dispatchTouchEvent直接返回false或者True,那么OnTouchEvent()和按钮都不会接收到这个事件了

    (2)ViewGroup对点击事件的分发机制

    再Activity分发事件的里面可以发现ViewGroup的事件分发也是从dispatchTouchEvent开始的,

    在ViewGroup的dispatchTouchEvent,ViewGroup每次事件分发时,都需调用onInterceptTouchEvent()询问是否拦截事件,

    ViewGroup.onInterceptTouchEvent()

      * 作用:是否拦截事件

      * 说明:

      *    a. 返回true = 拦截,即事件停止往下传递(需手动设置,即复写onInterceptTouchEvent(),从而让其返回true)

      *    b. 返回false = 不拦截(默认)

      */publicbooleanonInterceptTouchEvent(MotionEvent ev){returnfalse;  }

    如果没有拦截,通过for循环,遍历了当前ViewGroup下的所有子View

    / 判断当前遍历的View是不是正在点击的View,

    从而找到当前被点击的View// 若是,则进入条件判断内部

    // 条件判断的内部调用了该View的dispatchTouchEvent()// 即 实现了点击事件从ViewGroup到子View的传递

    // 调用子View的dispatchTouchEvent后是有返回值的// 若该控件可点击,那么点击时,dispatchTouchEvent的返回值必定是true,因此会导致条件判断成立// 于是给ViewGroup的dispatchTouchEvent()直接返回了true,即直接跳出// 即把ViewGroup的点击事件拦截掉

    如果onInterceptTouchEvent是拦截的状态

    那么返回true = 拦截,即事件停止往下传递,由ViewGroup自己的函数OnTouchEvent等等来处理这个事件

    (3)View对点击事件的分发机制

    总结:

    dispatchTouchEvent 和OnTouchEvent的结果一致,返回true代表事件被消费了

    有一层的OnTouchEvent返回了true

    被消费一定是在OnTouchEvent中消费,就是在哪一层消费的问题

    默认是dispatchTouchEvent的调用会一层一层的向下传递,

    OnTouchEvent会一层一层向上传递

    就是这个意思:

    Activity的dispatchTouchEvent 会调用到ViewGroup的dispatchTouchEvent,

    ViewGroup的dispatchTouchEvent会调用到View的dispatchTouchEvent对象

    如果有一层返回了true都代表事件被消费了

    如果都返回false,那么就回掉Activity的OnTouchEvent方法消费

    如果ViewGroup层的拦截器返回true代表拦截,那么就是ViewGroup这一层的OnTouchEvent消费事件

    如过默认条件下没有拦截,由view处理,就回掉view的OnTouchEvent消费

    如果没有传递到view层,那么onclick就不会被触发了

    相关文章

      网友评论

        本文标题:Android Touch分发事件机制详解

        本文链接:https://www.haomeiwen.com/subject/xeknhftx.html