Android的View体系(六):梳理总结View绘制的全流程
作者:互联网
一. 储备知识
1.1 ViewRoot
- 定义
连接器,对应于ViewRootImpl类 - 作用
连接WindowManager 和 DecorView
完成View的三大流程: measure、layout、draw - 特别注意
// 在主线程中,Activity对象被创建后:
// 1. 自动将DecorView添加到Window中 & 创建ViewRootImpll对象
root = new ViewRootImpl(view.getContent(),display);
// 3. 将ViewRootImpll对象与DecorView建立关联
root.setView(view,wparams,panelParentView)
1.2 DecorView
- 定义:顶层View
即 Android 视图树的根节点;同时也是 FrameLayout 的子类
- 作用:显示 & 加载布局
View层的事件都先经过DecorView,再传递到View
- 特别说明
内含1个竖直方向的LinearLayout,分为2部分:上 = 标题栏(titlebar)、下 = 内容栏(content)
在Activity中通过 setContentView()所设置的布局文件其实是被加到内容栏之中的,成为其唯一子View =
id为content的FrameLayout中
// 在代码中可通过content得到对应加载的布局
// 1. 得到content
ViewGroup content = (ViewGroup)findViewById(android.R.id.content);
// 2. 得到设置的View
ViewGroup rootView = (ViewGroup) content.getChildAt(0);
1.3 Window、Activity、DecorView 与 ViewRoot的关系
- 简介
- 之间的关系
二. 绘制准备
- 回忆上图,可看出最后1步 = 绘制
- 但在绘制前,系统会有一些绘制准备,即前面几个步骤:创建
PhoneWindow
类、DecorView
类、ViewRootmpl
类等。 - 主要包括:
DecorView
创建 & 显示
三. 绘制流程概述
-
从上可知,
View
的绘制流程开始于:ViewRootImpl
对象的performTraversals()
-
源码分析
/**
* 源码分析:ViewRootImpl.performTraversals()
*/
private void performTraversals() {
// 1. 执行measure流程
// 内部会调用performMeasure()
measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight);
// 2. 执行layout流程
performLayout(lp, mWidth, mHeight);
// 3. 执行draw流程
performDraw();
}
- 从上面的
performTraversals()
可知:View的绘制流程从顶级View(DecorView)
的ViewGroup
开始,一层一层从ViewGroup
至子View遍历测绘
即:自上而下遍历、由父视图到子视图、每一个 ViewGroup 负责测绘它所有的子视图,而最底层的 View 会负责测绘自身
- 绘制的流程 = measure过程、layout过程、draw过程,具体如下:
下面,我将详细讲解View绘制的三大流程:measure
过程、layout
过程、draw
过程
四. 详细介绍
4.1 Measure 过程
- 作用
测量View的宽 / 高
1.在某些情况下,需要多次测量(measure)才能确定View最终的宽/高;
2.该情况下,measure过程后得到的宽 / 高可能不准确;
3.此处建议:在layout过程中onLayout()去获取最终的宽 / 高
- 具体流程
4.2 Layout过程
- 作用
计算视图(View)的位置
即计算View的四个顶点位置:Left、Top、Right 和 Bottom
- 具体流程
4.3 Draw过程
-
作用
绘制View视图 -
具体流程
至此,关于View
的工作流程讲解完毕。
标签:ViewGroup,流程,content,DecorView,Android,绘制,梳理,View 来源: https://blog.csdn.net/gaolh89/article/details/104077473