欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android必备知识点之事件分发机制

程序员文章站 2022-07-14 19:59:13
...

1.基础知识

1.事件分发的本质:

当一个点击事件发生后,系统需要将这个事件传递给一个具体的View去处理。这个事件传递的过程就是分发过程。

2>.事件在哪些对象间传递?

一个点击事件产生后,传递顺序是:Activity(Window) -> ViewGroup -> View

3>.事件分发过程由哪些方法协作完成?

dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()

Android事件分发机制的本质是要解决:点击事件由哪个对象发出,经过哪些对象,最终达到哪个对象并最终得到处理。

2.伪代码

// 点击事件产生后,会直接调用dispatchTouchEvent()方法

public boolean dispatchTouchEvent(MotionEvent ev) {


    //代表是否消耗事件

    boolean consume = false;

    if (onInterceptTouchEvent(ev)) {

        //如果onInterceptTouchEvent()返回true则代表当前View拦截了点击事件

        //则该点击事件则会交给当前View进行处理

        //即调用onTouchEvent ()方法去处理点击事件

        consume = onTouchEvent (ev) ;
    } else {

        //如果onInterceptTouchEvent()返回false则代表当前View不拦截点击事件

        //则该点击事件则会继续传递给它的子元素

        //子元素的dispatchTouchEvent()就会被调用,重复上述过程

        //直到点击事件被最终处理为止

        consume = child.dispatchTouchEvent (ev) ;

    }


    return consume;

}

老生常谈了,就不详细研究了~

onTouch()返回true就认为该事件被onTouch()消费掉,因而不会再继续向下传递,即不会执行OnClick()。

3.滑动冲突及处理规则

场景:

①外层左右滑动,内部上下滑动

②内外同上同下

③外层左右,左右,内层上下

处理思路:

①外层滑动,外层View拦截点击事件;内层滑动,内层View拦截点击事件

②根据水平、竖直方向距离差判断

举例子的时候:viewPager已经帮我们解决滑动冲突了,可以说外层是水平scrollView,内层是listview

重点来了!!!!

外层拦截法:所有事件经过父容器的拦截处理,需要拦截则true,不需要则false,onInterceptTouchEvent中,不能在ACTION_DOWN中返回true拦截,因为会导致的所以事件都会交给父容器执行。一般在ACTION_MOVE中拦截,在ACTION_UP中再设置成false恢复。

内层拦截法:父容器不作处理,子容器去判断是否要消耗此事件,重写子容器的dispatchTouchEvent,配合requestDisallowIntercepTouchEvent(boolean),false是叫个父容器处理,true是让父容器不要拦截。