View
是 Android
开发者必须了解的基础View
原理的文章,但存在一些问题:内容不全、思路不清晰、无源码分析、简单问题复杂化等等View
的全工作流程,我能保证这是市面上的最全面、最清晰、最易懂的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)
View
即
Android
视图树的根节点;同时也是FrameLayout
的子类
View
层的事件都先经过DecorView
,再传递到View
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);
了解自定义View流程前,需了解一定的自定义View基础,具体请看文章:(1)自定义View基础 - 最易懂的自定义View原理系列
PhoneWindow
类、DecorView
类、ViewRootmpl
类等
故,下面我会先将绘制前的准备,再开始讲绘制流程
DecorView
创建 & 显示,具体请看文章:Android自定义View绘制前的准备: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
过程
View
的宽 / 高(measure)
才能确定View
最终的宽/高;measure
过程后得到的宽 / 高可能不准确;layout
过程中onLayout()
去获取最终的宽 / 高(View)
的位置即计算
View
的四个顶点位置:Left
、Top
、Right
和Bottom
请看文章:自定义View Layout过程 - 最易懂的自定义View原理系列(3)
View
视图
至此,关于自定义View
的工作流程讲解完毕。
measure
过程、layout
过程、draw
过程)来看,若要实现自定义View
,根据自定义View的种类不同(单一View
/ ViewGroup
),需自定义实现不同的方法onMeasure()
、onLayout()
、onDraw()
,具体如下结合原理 & 实现步骤,若需实现1个自定义View,请看文章:手把手教你写一个完整的自定义View
View
的原理。至此,关于自定义View
的绘制流程您应该非常熟悉了