【Android 事件分发】MotionEvent.ACTION_DOWN 按下事件分发流程( Activity | ViewGroup | View )

2023-03-29 14:57:57 浏览数 (2)

Android 事件分发 系列文章目录

【Android 事件分发】事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 )

【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )

【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

【Android 事件分发】ItemTouchHelper 简介 ( 拖动/滑动事件 | ItemTouchHelper.Callback 回调 )

【Android 事件分发】ItemTouchHelper 实现侧滑删除 ( 设置滑动方向 | 启用滑动操作 | 滑动距离判定 | 滑动速度判定 | 设置动画时间 | 设置侧滑触发操作 )

【Android 事件分发】ItemTouchHelper 实现拖动排序 ( 设置滑动方向 | 启启用长按拖动功能 | 拖动距离判定 | 设置拖动触发操作 )

【Android 事件分发】ItemTouchHelper 事件分发源码分析 ( 绑定 RecyclerView )

【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )

【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )

【Android 事件分发】MotionEvent.ACTION_DOWN 按下事件分发流程( Activity | ViewGroup | View )


文章目录

  • Android 事件分发 系列文章目录
  • 一、事件分发相关类和方法
  • 二、Activity 的事件传递
    • 1、Activity.dispatchTouchEvent 方法事件传递机制
    • 2、Activity.onTouchEvent 方法事件传递机制
  • 三、ViewGroup 的事件传递
    • 1、ViewGroup.dispatchTouchEvent 方法事件传递机制
    • 2、ViewGroup.onInterceptTouchEvent 方法事件传递机制
    • 3、ViewGroup.onTouchEvent 方法事件传递机制
  • 四、View 的事件传递
    • 1、View .dispatchTouchEvent 方法事件传递机制
    • 2、View .onTouchEvent 方法事件传递机制
  • 五、事件分发示意图
  • 总结

一、事件分发相关类和方法


Android 事件分发涉及到的类有

3

个 , Activity , ViewGroup , View ;

Android 事件分发涉及到的如下

7

个方法 :

  • Activity 类涉及到 dispatchTouchEvent , onTouchEvent ,
2

个方法 ;

代码语言:javascript复制
public class MainActivity extends AppCompatActivity {
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
}
  • ViewGroup 涉及到 dispatchTouchEvent , onInterceptTouchEvent , onTouchEvent ,
3

个方法 ;

代码语言:javascript复制
public class MyConstraintLayout extends ConstraintLayout {
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
}
  • View 涉及到 dispatchTouchEvent , onTouchEvent ,
2

个方法 ;

代码语言:javascript复制
public class MyButton extends androidx.appcompat.widget.AppCompatButton {
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
}

二、Activity 的事件传递


1、Activity.dispatchTouchEvent 方法事件传递机制

事件来源 :

① 驱动层产生触摸事件, 由 WindowManagerService 传递到 Activity

事件分发 :

① 停止传递 : 如果返回 true / false , 说明事件被消费 , 停止传递

② 继续传递 : 如果返回 super.dispatchTouchEvent(ev) , 那么继续向下传递, 按照如下顺序逐层传递 : Activity -> PhoneWindow -> DecorView -> ViewGrope , 最终传递到 ViewGroup, 调用 ViewGroup 的 dispatchTouchEvent 方法

代码语言:javascript复制
    /**
     * 该方法是页面事件分发入口
     *
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      驱动层产生触摸事件, 由 WindowManagerService 传递到 Activity
     *  事件分发 :
     *      如果返回 true / false, 说明事件被消费, 停止传递
     *      如果返回 super.dispatchTouchEvent(ev), 那么继续向下传递, 按照如下顺序逐层传递 :
     *          Activity -> PhoneWindow -> DecorView -> ViewGrope
     *          最终传递到 ViewGroup, 调用 ViewGroup 的 dispatchTouchEvent 方法
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

2、Activity.onTouchEvent 方法事件传递机制

事件来源 :

① 布局容器 ViewGroup 的 dispatchTouchEvent 方法返回 false ;

② 布局容器 ViewGroup 的 onTouchEvent 方法返回 false / super.onTouchEvent(event) ;

事件分发 : 这是事件传递的终点, 返回值无所谓

① 返回 true 说明事件被消费了 ;

代码语言:javascript复制
    /**
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      布局容器 ViewGroup 的 dispatchTouchEvent 方法返回 false
     *      布局容器 ViewGroup 的 onTouchEvent 方法返回 false / super.onTouchEvent(event)
     *   事件分发 : 这是事件传递的终点, 返回值无所谓
     *      返回 true 说明事件被消费了
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }

三、ViewGroup 的事件传递


1、ViewGroup.dispatchTouchEvent 方法事件传递机制

代码语言:javascript复制
    /**
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      从 Activity 的 dispatchTouchEvent 传递而来
     *      从父容器 ViewGroup 的 dispatchTouchEvent 传递而来
     *  事件分发 :
     *      如果返回 true, 表示事件被消费, 停止传递
     *      如果返回 false, 则传递给父控件的 onTouchEvent 方法
     *      如果返回 super.dispatchTouchEvent(ev) , 则继续向下传递到 onInterceptTouchEvent 方法
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

2、ViewGroup.onInterceptTouchEvent 方法事件传递机制

代码语言:javascript复制
    /**
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      从 本类 的 dispatchTouchEvent 方法传递而来
     *  事件分发 :
     *      返回 true, 则停止向后传递, 执行本类的 onTouchEvent 方法
     *          如果需要拦截, 返回true
     *      返回 false / super.onInterceptTouchEvent(ev),
     *          则继续向 子容器/子组件 的 dispatchTouchEvent 方法传递; ( 这里是子组件 )
     *          默认不拦截
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }

3、ViewGroup.onTouchEvent 方法事件传递机制

代码语言:javascript复制
    /**
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      本类的 onInterceptTouchEvent 方法返回 true
     *      子组件/子容器 的 dispatchTouchEvent 方法返回 false
     *      子组件/子容器 的 onTouchEvent 方法返回 false / super.onTouchEvent(event)
     *   事件分发 :
     *      返回 true 说明事件被消费了, 不再向下传递
     *      返回 false / super.onTouchEvent(event) , 则需要继续向下传递
     *          向父容器的 onTouchEvent 传递
     *
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }

四、View 的事件传递


1、View .dispatchTouchEvent 方法事件传递机制

代码语言:javascript复制
    /**
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      父容器 ViewGroup 的 onInterceptTouchEvent 如果返回 false / super.onInterceptTouchEvent(ev)
     *          将事件传递到该方法
     *  事件分发 :
     *      如果返回 true, 表示事件被消费, 停止传递
     *      如果返回 false, 则传递给父控件的 onTouchEvent 方法
     *      如果返回 super.dispatchTouchEvent(ev) , 则向本类的 onTouchEvent 方法传递
     *
     * @param event
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

2、View .onTouchEvent 方法事件传递机制

代码语言:javascript复制
    /**
     * 针对 ACTION_DOWN 事件分析 :
     *  事件来源 :
     *      本类的 dispatchTouchEvent 方法返回 super.dispatchTouchEvent(event)
     *   事件分发 :
     *      返回 true 说明事件被消费了, 不再向下传递
     *      返回 false / super.onTouchEvent(event) , 则需要继续向下传递
     *          向父容器的 onTouchEvent 传递
     *
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }

五、事件分发示意图


网上找了两张示意图 , 参考上述源码注释理解 ;

总结

通过控制上述

7

个方法的

3

种返回值 true / false / super , 控制整体 Activity 界面组件的事件分发 ;

事件分发规律 :

① 事件消费 : dispatchTouchEvent 或 onTouchEvent , 一旦返回 true , 则标明事件消费 , 不再继续分发事件 ; 注意 : Activity 的 dispatchTouchEvent 除外 , 其返回 true / false 都表示事件已消费 , 只有 super 时才向下传递 ;

② 向父容器传递 : dispatchTouchEvent 或 onTouchEvent , 一旦返回 false , 一律将事件传递给父容器的 onTouchEvent 方法 ;

③ 事件拦截 : onInterceptTouchEvent 返回 true , 则执行自己的 , 返回 false 则传递到子组件的 dispatchTouchEvent 方法 ;

0 人点赞