Android 事件分发MotionEvent.ACTION_DOWN 按下事件分发流程( Activity | ViewGroup | View )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 事件分发MotionEvent.ACTION_DOWN 按下事件分发流程( Activity | ViewGroup | View )相关的知识,希望对你有一定的参考价值。
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 事件分发涉及到的类有 3 3 3 个 , Activity , ViewGroup , View ;
Android 事件分发涉及到的如下 7 7 7 个方法 :
- Activity 类涉及到 dispatchTouchEvent , onTouchEvent , 2 2 2 个方法 ;
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 3 3 个方法 ;
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 2 2 个方法 ;
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 方法
/**
* 该方法是页面事件分发入口
*
* 针对 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 说明事件被消费了 ;
/**
* 针对 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 方法事件传递机制
/**
* 针对 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 方法事件传递机制
/**
* 针对 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 方法事件传递机制
/**
* 针对 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 方法事件传递机制
/**
* 针对 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 方法事件传递机制
/**
* 针对 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 7 7 个方法的 3 3 3 种返回值 true / false / super , 控制整体 Activity 界面组件的事件分发 ;
事件分发规律 :
① 事件消费 : dispatchTouchEvent 或 onTouchEvent , 一旦返回 true , 则标明事件消费 , 不再继续分发事件 ; 注意 : Activity 的 dispatchTouchEvent 除外 , 其返回 true / false 都表示事件已消费 , 只有 super 时才向下传递 ;
② 向父容器传递 : dispatchTouchEvent 或 onTouchEvent , 一旦返回 false , 一律将事件传递给父容器的 onTouchEvent 方法 ;
③ 事件拦截 : onInterceptTouchEvent 返回 true , 则执行自己的 , 返回 false 则传递到子组件的 dispatchTouchEvent 方法 ;
以上是关于Android 事件分发MotionEvent.ACTION_DOWN 按下事件分发流程( Activity | ViewGroup | View )的主要内容,如果未能解决你的问题,请参考以下文章
Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 三 )
Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 二 )
Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 一 )
Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 七 )