★60.自定义控件 ★17.事件分发机制原理

View结构

简介

  • AndroidView是树形结构的,View可能会重叠在一起,当触摸的地方有多个View都可以响应的时候由 事件分发机制 决定该由谁响应。
    ★60.自定义控件 ★17.事件分发机制原理_第1张图片

示意图

★60.自定义控件 ★17.事件分发机制原理_第2张图片

DecorView

  • 主题颜色和标题栏等内容就是显示在DecorView中的。

PhoneWindow

  • Window是一个抽象类,是所有视图的最顶层容器,视图的外观和行为都归他管,而PhoneWindowWindow的唯一实现类。

事件分发、拦截与消费

类型 相关方法 Activity ViewGroup View
事件分发 dispatchTouchEvent()
事件拦截 onInterceptTouchEvent() X X
事件消费 onTouchEvent()
  • ActivityView都是没有 事件拦截 的,因为:
    • Activity作为原始的事件分发者,如果Activity拦截了事件会导致整个屏幕都无法响应事件。
    • View最为事件传递的最末端,要么消费掉事件,要么不处理进行回传,无需 事件拦截

事件分发流程

流程简介

  1. 事件正向传递View是树形结构的,基于这样的结构,事件收集之后最先传递给Activity,依次向下传递:
    • Activity -> PhoneWindow -> DecorView -> ViewGroup -> ... -> View
  2. 事件反向回传 :如果最后分发到View,如果这个View也没有处理事件,那么会发生 事件反向回传 ,最终传回给Activity,如果最后Activity也没有处理,本次事件才会被抛弃:
    • Activity <- PhoneWindow <- DecorView <- ViewGroup <- ... <- View

情景分析

示意图

★60.自定义控件 ★17.事件分发机制原理_第3张图片

情景一:点击View1区域但没有View消费事件。

★60.自定义控件 ★17.事件分发机制原理_第4张图片

情景二:点击View1区域且事件被View1消费

★60.自定义控件 ★17.事件分发机制原理_第5张图片

情景三:点击View1区域但事件被ViewGroupA拦截

★60.自定义控件 ★17.事件分发机制原理_第6张图片

总结

  • 从根往叶传递时决定是否拦截:onInterceptTouchEvent()是从根部开始的,根据返回值判断事件是否拦截。
  • 从叶往根回传时决定是否消费掉:onTouchEvent()是从叶部开始的,根据返回值来判断事件是否消费。

你可能感兴趣的:(★60.自定义控件 ★17.事件分发机制原理)