《android高级进阶》学习笔记(二) View的绘制流程

1 View的绘制流程
1.1 Android中View存在的2种形式:
①单一的View控件;
②包含其它View的ViewGroup容器。

1.2 Android UI管理系统层级关系,如下图:
《android高级进阶》学习笔记(二) View的绘制流程
1.3 Android视图绘制的过程:
①整体流程:ViewRoot:performTraversals()→ViewGroup→View。
②绘制步骤:Measure(测量)→Layout(布局)→Draw(绘制)。

1.3.1 MeasureSpec
MeasureSepc:一个32位的整型值,高2位表示SpecMode(测量模式),低30位表示某种SpecMode下的SpecSize(规格大小)。

1.3.2 SpecMode(测量模式)
① UNSPECIFIED:不指定测量模式,父视图没有限制子视图的大小,子视图可以是任意尺寸,通常用于系统内部,应用开发中很少使用;
② EXACTLY:精确测量模式,当视图的layout_width或者layout_height指定为具体数值或者match_parent时生效,表示父视图已经决定了子视图的精确大小,该模式下View的测量值就是SpecSize的值;
③AT_MOST:最大值测量模式,当视图的layout_width或者layout_height指定为wrap_content时生效,表示子视图的尺寸可以是不超过父视图允许的最大尺寸的任何尺寸。
对DecorView而言,它的MeasureSpec由窗口尺寸和其自身的LayoutParams共同决定;
对普通View而言,它的MeasureSpec由父视图的MeasureSpec和其自身的LayoutParams共同决定。

1.3.3 Measure(测量)
Measure是计算View的实际大小,具体的测量操作是由ViewRoot的performMeasure分发到ViewGroup,再由ViewGroup的measureChild方法中传递给子View,ViewGroup通过遍历自身所有的子View,并逐个调用子View的measure方法实现测量操作。在View(ViewGroup)的measure方法中,最终的测量是通过回调onMeasure方法实现的,通常由View的特定子类自己实现,可通过重写此方法实现自定义View。

1.3.4 Layout(布局)
Layout用来确定View在父容器中的布局位置,由父容器获取子View的位置参数后,调用View的layout方法并将位置参数传入实现的。重写onLayout方法,可实现自定义View的布局流程,若重写ViewGroup的该方法,可实现ViewGroup中所有View控件的布局流程。

1.3.5 Draw(绘制)
Draw操作用来将控件绘制出来,绘制的流程从ViewRoot的performDraw方法开始,最终调用到每个View的draw方法绘制每个具体的View,绘制基本分为六个步骤:
① 绘制View的背景;——>DrawBackground
② 保存canvas的图层,为fading做准备;———->canvas.getSaveCount()
③ 绘制View的内容;———> onDraw(canvas)
④ 绘制View的子View;———–>dispatchDraw(canvas)
⑤ 绘制View的fading边缘并恢复图层;canvas.drawRect(….);canvas.restoreToCount(….);
⑥绘制View的装饰(如滚动条)onDrawScrollBars(canvas);