参考自:一文梳理自定义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的关系
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
总结:在onMeasure()中通过getDefaultSize()根据测量规格测量view的宽高值,然后调用setMeasureDimension()把值存储起来。
4.2.ViewGroup的measure
总结:需复写onMeasure()方法,然后遍历所有子view,调用子view的measure()方法测量出所有子view的宽高值后,调用setMeasureDimension存储测量的宽高值。
5.Layout布局
5.1.单一view的layout
参考自:# 自定义View 布局过程(Layout)
总结:在layout()中调用setFrame()存储自身的位置信息,完成自身的布局.
5.2.ViewGroup的layout
总结:复写onLayout(),递归循环遍历所有子view,并逐个调用子view的layout(),确定所有子view的位置.
5.Draw绘制
参考自# 自定义View 绘制过程(Draw)
5.1.单一view的draw
总结:复写onDraw()方法完成自身绘制,dispatchDraw()空实现.
5.2.ViewGroup的draw
总结:复写onDraw()完成自身绘制,然后由dispatchDraw()遍历完成所有子view的绘制.