View绘制流程笔记

223 阅读2分钟

参考自:一文梳理自定义View工作流程

1.知识储备

1.1:ViewRoot
定义:连接器,对应ViewRootImpl类
作用:连接WindowManager和DecorView,完成View的三大流程(measure(),layout(),draw())
1.2:DecorView
定义:顶层View,android树的根节点,同时也是FrameLayout的子类(内部分为title和content).
作用:显示&加载布局,view层的事件都先经过decorview,再传递到view.
1.3:Activity,Window,DecorView与ViewRoot的关系
1663291061640.jpg

2.绘制准备

2.1:DecorView的创建:首先在Activity的onAttach()中创建PhoneWindow对象,然后在onCreate()中调用Activity.setContentView()->PhoneWindow.setContentView()中创建DecorView对象,并把布局添加到DecorView对象中.
2.2:DecorView的显示:首先在ActivityThread.handleResumeActivity()中获取PhoneWindow实例的DecorView对象,然后添加到WindowManager中,再由WindowManager的实现类WindowManagerImpl类创建ViewRootImpl对象,最后WindowManager将DecorView实例交给ViewRootImpl,并在scheduleTraversals()中通过mHandler.post发送runnable消息最终会调用performTraversals()进行view的三大流程绘制(measure,layout,draw)

3.绘制流程概述

view的绘制流程始于ViewRootImpl的performTraversales()

4.Measure测量过程

参考自# 自定义View 测量过程(Measure)
4.1.单一view的measure 1.webp 2.webp
总结:在onMeasure()中通过getDefaultSize()根据测量规格测量view的宽高值,然后调用setMeasureDimension()把值存储起来。

4.2.ViewGroup的measure image.png 总结:需复写onMeasure()方法,然后遍历所有子view,调用子view的measure()方法测量出所有子view的宽高值后,调用setMeasureDimension存储测量的宽高值。

5.Layout布局

5.1.单一view的layout 参考自:# 自定义View 布局过程(Layout) image.png
总结:在layout()中调用setFrame()存储自身的位置信息,完成自身的布局.
5.2.ViewGroup的layout image.png 总结:复写onLayout(),递归循环遍历所有子view,并逐个调用子view的layout(),确定所有子view的位置.

5.Draw绘制

参考自# 自定义View 绘制过程(Draw)
5.1.单一view的draw image.png 总结:复写onDraw()方法完成自身绘制,dispatchDraw()空实现.
5.2.ViewGroup的draw
image.png 总结:复写onDraw()完成自身绘制,然后由dispatchDraw()遍历完成所有子view的绘制.