View结构
简介
-
Android 的
View
是树形结构的,View
可能会重叠在一起,当触摸的地方有多个View
都可以响应的时候由 事件分发机制 决定该由谁响应。
示意图
![](https://img.haomeiwen.com/i4603989/15068ec19ab7cad3.jpg)
DecorView
- 主题颜色和标题栏等内容就是显示在
DecorView
中的。
PhoneWindow
-
Window
是一个抽象类,是所有视图的最顶层容器,视图的外观和行为都归他管,而PhoneWindow
是Window
的唯一实现类。
事件分发、拦截与消费
类型 | 相关方法 | Activity | ViewGroup | View |
---|---|---|---|---|
事件分发 | dispatchTouchEvent() |
√ | √ | √ |
事件拦截 | onInterceptTouchEvent() |
X | √ | X |
事件消费 | onTouchEvent() |
√ | √ | √ |
-
Activity
和View
都是没有 事件拦截 的,因为:-
Activity
作为原始的事件分发者,如果Activity
拦截了事件会导致整个屏幕都无法响应事件。 -
View
最为事件传递的最末端,要么消费掉事件,要么不处理进行回传,无需 事件拦截 。
-
事件分发流程
流程简介
-
事件正向传递 :
View
是树形结构的,基于这样的结构,事件收集之后最先传递给Activity
,依次向下传递:Activity -> PhoneWindow -> DecorView -> ViewGroup -> ... -> View
-
事件反向回传 :如果最后分发到
View
,如果这个View
也没有处理事件,那么会发生 事件反向回传 ,最终传回给Activity
,如果最后Activity
也没有处理,本次事件才会被抛弃:Activity <- PhoneWindow <- DecorView <- ViewGroup <- ... <- View
情景分析
示意图
![](https://img.haomeiwen.com/i4603989/3f72c96662417b34.jpg)
情景一:点击View1
区域但没有View
消费事件。
![](https://img.haomeiwen.com/i4603989/84e87656ab6428b4.jpg)
情景二:点击View1
区域且事件被View1
消费
![](https://img.haomeiwen.com/i4603989/507d545c563f8324.jpg)
情景三:点击View1
区域但事件被ViewGroupA
拦截
![](https://img.haomeiwen.com/i4603989/e997684380fdcdf7.jpg)
总结
- 从根往叶传递时决定是否拦截:
onInterceptTouchEvent()
是从根部开始的,根据返回值判断事件是否拦截。 - 从叶往根回传时决定是否消费掉:
onTouchEvent()
是从叶部开始的,根据返回值来判断事件是否消费。
网友评论