【Android】图解View事件分发机制

文章目录

View事件分发机制

View的事件分发机制是Android中非常核心的一个概念,它负责处理触摸事件(如按下、移动、抬起等)的分发过程。事件分发主要涉及三个方法:dispatchTouchEvent(), onInterceptTouchEvent(), 和 onTouchEvent()

点击事件的分发有三个重要方法,大概可以表示为:

java 复制代码
public boolean dispatchTouchEvent(MotionEvent ev){
    boolean result = false;
    if(onInterceptTouchEvent(ev)){
        result = onTouchEvent(ev);
    }else{
        result = child.dispatchTouchEvent(ev);
    }
    return result;

}

dispartchTouchEvent()

View 的事件分发机制主要是通过 dispatchTouchEvent() 方法来完成的。

当一个触摸事件发生时,这个事件首先会被传递到顶层的 ViewGroup(比如一个 Activity 的根布局),然后通过 dispatchTouchEvent() 方法来决定如何分发这个事件。

tip: onInterceptTouchEvent(ev)默认返回false

dispatchTouchEvent() 方法主要负责什么?

onTouchEvent(event)

  1. 触摸事件发生:
  • 用户触摸屏幕时,系统生成一个 MotionEvent 对象,并将其传递给顶层的 ViewGroup(如一个 Activity 的根布局)
  1. dispatchTouchEvent():
  • MotionEvent 首先被传递到 ViewGroup 的 dispatchTouchEvent() 方法。
  • dispatchTouchEvent() 方法负责决定是否将事件传递给子 View,或者直接处理。
  • 对于 ViewGroup,它会首先调用 onInterceptTouchEvent() 来决定是否拦截该事件。如果不拦截,事件会继续向下传递。
  1. 向子View传递:
  • 如果 ViewGroup 没有拦截事件,dispatchTouchEvent() 会按照事件坐标递归地将事件传递给子 View 的 dispatchTouchEvent()。
  1. 到达目标View:
  • 当事件传递到目标 View(没有子 View 或者子 View 不处理该事件的 View),该 View 的 dispatchTouchEvent() 会被调用。
  1. onTouchEvent():
  • 在目标 View 的 dispatchTouchEvent() 中,如果该 View 是处理事件的正确位置,它会调用自己的 onTouchEvent() 方法来处理具体的触摸事件。
  • onTouchEvent() 方法根据传入的 MotionEvent 对象的不同动作(如 ACTION_DOWN、ACTION_MOVE、ACTION_UP 等)执行不同的逻辑,以响应用户的触摸操作。
  1. 事件消费判断:
  • 如果 onTouchEvent() 方法返回 true,表示该 View 消费了这个事件,后续的触摸事件(如多次 ACTION_MOVE 和最终的 ACTION_UP)也会直接传递给该 View 的 onTouchEvent() 方法处理。
  • 如果 onTouchEvent() 返回 false,表示该 View 未消费事件,那么事件会回溯到父 ViewGroup,并尝试由父 ViewGroup 的 onTouchEvent() 方法处理。

点击事件分发的传递规则

Android 中的点击事件(以及所有触摸事件)的分发过程可以概括为两个方向的传递:自上而下(downwards)的事件分发自下而上(upwards)的事件回溯

自上而下

  1. 从顶层开始:
  • 事件首先被传递到根 ViewGroup(如一个 Activity 的内容视图)。
  1. 递归向下:
  • 根 ViewGroup 的 dispatchTouchEvent() 方法被调用。如果它有子 View,则可能会调用 onInterceptTouchEvent() 来决定是否拦截事件。
  • 如果 onInterceptTouchEvent() 返回 false,根 ViewGroup 不拦截事件,事件继续向下传递到子 View 的 dispatchTouchEvent() 方法。
  • 这个过程递归进行,直到事件到达最终的目标 View,或者被某个 ViewGroup 的 onInterceptTouchEvent() 拦截。
  1. 目标View处理:
  • 当事件到达一个具体的 View,并且没有被拦截,那么这个 View 的 dispatchTouchEvent() 方法会调用 onTouchEvent() 来处理事件

自下而上

  1. 处理判断:
  • 如果事件到达的目标 View 的 onTouchEvent() 方法返回 true,则表示事件被消费,事件分发过程结束。
  • 如果返回 false,则表示事件没有被消费,需要向上传递给父 ViewGroup。
  1. 事件回溯:
  • 未被消费的事件会回溯到上一个 ViewGroup,它的 onTouchEvent() 方法会被调用。
  • 如果父 ViewGroup 的 onTouchEvent() 也返回 false,事件继续向上传递,这个过程会一直持续到回到根 ViewGroup。
  1. 顶层处理或丢失:
  • 如果所有的 View 和 ViewGroup 都未处理该事件(即连根 ViewGroup 的 onTouchEvent() 也返回 false),则该事件会被视为丢失,不再被处理。
相关推荐
zlpzpl12 分钟前
Linux系统下安装配置Nginx(保姆级教程)
java·linux·nginx
好家伙VCC17 分钟前
# 发散创新:用Python+Pandas构建高效BI数据清洗流水线在现代数据分析领域,**BI(商业智能)工具的核心竞
java·python·数据分析·pandas
文艺倾年26 分钟前
【源码精讲+简历包装】LeetcodeRunner—手搓调试器轮子(20W字-下)
java·开发语言·人工智能·语言模型·自然语言处理·大模型·免训练
松叶似针27 分钟前
Flutter三方库适配OpenHarmony【secure_application】— Android 端 FLAG_SECURE 实现分析
android·flutter
海兰43 分钟前
Elastic Stack 9.3.0 日志探索
java·服务器·前端
invicinble1 小时前
centos7系统安装jdk
java·开发语言
lifallen1 小时前
笛卡尔树 (Cartesian Tree)
java·数据结构·算法
不想看见4041 小时前
N-Queens -- 回溯法 -- 力扣101算法题解笔记
java·数据结构·算法
MX_93591 小时前
Spring组件扫描原理解析
java·后端·spring
让我上个超影吧2 小时前
天机学堂——领取优惠券优化
java