概述
关于View的绘制我阅读过的所有博文都很长,一篇文章看下来至少要花两三个小时,才能看个大概,包括其中的源码分析等。今天这篇文章主要是针对View的绘制做下大概的汇总,不会很详细,网上关于View的绘制流程详细介绍有很多,大家自行百度吧。这篇文章的目的是假如有人问你的时候,比如面试官,你能用简单的话语介绍给他听,尽管是简答,但是该有的还是要有。
介绍几个View
先看一个图:
解释如下:
PhoneWindow:将Decoriew设置为整个应用窗口的根View,是Window的实现类,它是Android中的最基本的窗口;DsecorView:又叫顶级View,系统会将要显示的具体内容呈现在PhoneWindow上。一般情况下,它的内部会包含一个竖直方向的LinearLayout,在这个layout中有两个部分:title和content,DecorView可以通过View view = getWindow().getDecorView()获得。它还是PhoneWindow与ViewRoot之间的桥梁,ViewRoot会通过DecorView设置窗口属性;DecorView中的TitleView:标题栏,一般指的是toolbar。DecorView中的ContentView:内容栏,是一个id为content的Framelayout,我们平时所写的setContentView()其实就是在设置它。
源码分析
通常我们自定义View的时候可能会用到view.setBackgroundColor(),或是布局中添加View(view.addView()),这些都能引发View的绘制。并且这些都是依附于Activity的,也就是说没有Activity就没有View的绘制。看下Activity的生命周期回调ActivityThead.class:
了解到Activity的生命周期回调原理,我们知道View的绘制就是在onResume中开始的。
wm其实就是WindowManagerImpl,而在WindowManagerImpl中又调用了WindowManagerGlobal的addView方法。
将DecorView添加到Window中,同时创建ViewRootImp对象WindowManagerGlobal.java:
以上前期的准备工作完成后,
View的绘制流程是从ViewRoot(ViewRootImpl)的performTraversals()方法开始的ViewRootImpl.java:
说是简答,感觉越写越长。。。刹不住车了
View的绘制流程是从 ViewRoot 的 performTraversals 方法开始的,它经过 measure、layout、draw三个过程才最终将一个View绘制出来,performTraversals会依次调用 performMeasure,performLayout和 performDraw 三个方法,这三个方法分别会完成View的measure、layout、draw的流程。例如performMeasure会调用measure方法,measure方法中又会调用onMeasure方法,在onMeasure方法中会对所有子view进行measure过程,子view再重复此过程,如此反复就实现了view树的遍历。参数:(widthMeasureSpec,heightMeasureSpec)高2位表示MODE,低30位表示size。当然在measure、layout、draw中还有许多的细节,这里就不讲了。
总结一下
准备阶段
启动Activity ——> 创建一个PhoneWindow ——> getWindow().setContentView(id)下初始化DecorView ——> onRsume()下将DecorView添加到Window中,同时创建ViewRootImp对象 ——> performTraversals()
绘制阶段
performTraversals()会依次调用performMeasure、performLayout和performDraw ,然后就是各种遍历计算,绘制子view