• Android事件分发机制详解


    事件分发机制详解

    一、基础知识介绍

    1、经常用的事件有:MotionEvent.ACTION_DOWNMotionEvent.ACTION_MOVEMotionEvent.ACTION_UP

    2、常用的方法有:disPatchTouchEvent()onTouchEvent()onInterceptTouchEvent()(只有ViewGroup才有这个方法,View没有这个方法,且ViewGroupView的子类);

    二、方法功能介绍

    1dispatchTouchEvent事件分发的调度者与指挥者,触发的第一个方法

    2onInterceptTouchEvent,决定是否拦截事件:

    3、如果拦截事件,调用当前控件的onTouchEvent方法,

    4、如果不拦截,判断是否有子控件,

    5onTouchEvent,决定是否消费事件,消费返回True,不消费返回False。如果返回的为false,之后的事件都不会再传递到当前的控件了(会不再访问当前控件),如果返回true,之后的事件依然还是会传递过来的。

    三、各个方法和控件之间事件传递关系

    事件传递流程:事件—>Activity>Window>DecorView>ViewTree(嵌套在一起的各种控件)

    一个事件,首先会由ActivitydispatchTouchEvent方法接受,然后分发到附着在Activity上的WindowWindow不进行处理直接分发到ViewTree;最外层的ViewTop(默认为是ViewGroup类型的)会先调用自己的dispatchTouchEvent方法,然后由dispatchTouchEvent调用onInterceptTouchEvent方法,如果返回true,调用自己的onTouchEvent方法;如果返回false,继续向下一个控件进行事件分发。

    如果ViewTree中的所有控件都不消费,那就返回到Activity中,由Activity调用onTouchEvent方法。

    下面给大家一个具体的例子,大家可以有一个形象的感受。

     

    四、示例Demo(示例中的代码是不考虑下面说的特殊情况的)

    布局文件

    <VP1>

    <VP2>

    <CustomView/>

    </VP2>

    </VP1>

    1、控件都不消费

    down事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-VP1:dispatchTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:返回:false

    Log:-CustomView:dispatchTouchEvent:调用

    Log:-CustomView:touchEvent:调用

    Log:-CustomView:touchEvent:返回:false

    Log:-CustomView:dispatchTouchEvent:返回:false

    Log:-VP2:touchEvent:调用

    Log:-VP2:touchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:返回:false

    Log:-VP1:touchEvent:调用

    Log:-VP1:touchEvent:返回:false

    Log:-VP1:dispatchTouchEvent:返回:false

    Log:-Activity:touchEvent:调用

    Log:-Activity:touchEvent:返回:false

    Log:-Activity:dispatchTouchEvent:返回:false

    up事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-Activity:touchEvent:调用

    Log:-Activity:touchEvent:返回:false

    Log:-Activity:dispatchTouchEvent:返回:false

     

    2、CustomView消费

    down事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-VP1:dispatchTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:返回:false

    Log:-CustomView:dispatchTouchEvent:调用

    Log:-CustomView:touchEvent:调用

    Log:-CustomView:touchEvent:返回:true

    Log:-CustomView:dispatchTouchEvent:返回:true

    Log:-VP2:dispatchTouchEvent:返回:true

    Log:-VP1:dispatchTouchEvent:返回:true

    Log:-Activity:dispatchTouchEvent:返回:true

    Up事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-VP1:dispatchTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:返回:false

    Log:-CustomView:dispatchTouchEvent:调用

    Log:-CustomView:touchEvent:调用

    Log:-CustomView:touchEvent:返回:true

    Log:-CustomView:dispatchTouchEvent:返回:true

    Log:-VP2:dispatchTouchEvent:返回:true

    Log:-VP1:dispatchTouchEvent:返回:true

    Log:-Activity:dispatchTouchEvent:返回:true

     

    3、VP2拦截不消费

    Down事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-VP1:dispatchTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:返回:true

    Log:-VP2:touchEvent:调用

    Log:-VP2:touchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:返回:false

    Log:-VP1:touchEvent:调用

    Log:-VP1:touchEvent:返回:false

    Log:-VP1:dispatchTouchEvent:返回:false

    Log:-Activity:touchEvent:调用

    Log:-Activity:touchEvent:返回:false

    Log:-Activity:dispatchTouchEvent:返回:false

    UP事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-Activity:touchEvent:调用

    Log:-Activity:touchEvent:返回:false

    Log:-Activity:dispatchTouchEvent:返回:false

    4、VP2拦截消费

    Down事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-VP1:dispatchTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:调用

    Log:-VP2:onInterceptTouchEvent:返回:true

    Log:-VP2:touchEvent:调用

    Log:-VP2:touchEvent:返回:true

    Log:-VP2:dispatchTouchEvent:返回:true

    Log:-VP1:dispatchTouchEvent:返回:true

    Log:-Activity:dispatchTouchEvent:返回:true

    UP事件

    Log:-Activity:dispatchTouchEvent:调用

    Log:-VP1:dispatchTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:调用

    Log:-VP1:onInterceptTouchEvent:返回:false

    Log:-VP2:dispatchTouchEvent:调用

    Log:-VP2:touchEvent:调用

    Log:-VP2:touchEvent:返回:true

    Log:-VP2:dispatchTouchEvent:返回:true

    Log:-VP1:dispatchTouchEvent:返回:true

    Log:-Activity:dispatchTouchEvent:返回:true

     

    五、特殊情况

    1、如果disallowIntercept=true,那么不会再走控件中的onInterceptTouchEvent方法,直接标记为不拦截事件。

    2、如果有requestDisallowInterceptTouchEvent(true)方法,父类控件不走onInterceptTouchEvent方法,不用通过回调来判断是否需要拦截事件,而是直接进行传送。

    3、这两方面,主要是用来解决手势冲突的。

    六、小提示

    1、如果满足下列条件之一,就会调用onTouchEvent方法。

    1. 所处的view拦截了事件
    2. 没有子View
    3. View都不消费事件

    2、onTouchListener中的onTouch回调与dispatchTouchEvent的优先级一样,都是优先于onTouchEvent

  • 相关阅读:
    jQuery扩展extend一
    json对象的操作,json工具
    typeof操作符的返回值
    jacksonall的使用,解析json
    jQuery的扩展
    An Introduction to Computer Thinking
    lazy初始化和线程安全的单例模式
    Compiler Principle
    Lineare Algebra
    Mathematik
  • 原文地址:https://www.cnblogs.com/zxxiaoxia/p/5279878.html
Copyright © 2020-2023  润新知