1.View的绘制流程
一般来说View的绘制流程分为三个步骤
measure(测量),通过measure来确定View的大小(即宽高)
layout(布局),通过layout来确定View的位置(即在屏幕的具体位置)
draw(绘制),,通过draw来绘制View所需要显示的内容
2.从哪里入口
在开发中,我们通常都会在Activity里写这么一句话setContentView(int)来实现我们想要的布局,页面通常都是依附于Window之上的,而DecorView是窗口上最顶级的视图,DecorView本身也是继承于FrameLayout,它里面的布局如下。
所以我们在调用setContentView的时候,其实就是把我们的布局给添加到R.id.content的布局上面,然后我们在回来View的绘制.
3.ViewRootImp
通过ViewRoot来绘制View,而ViewRoot的实现类为ViewRootImp,当Activity创建完成之后,会将DecorView添加到窗口Window之中,同时会创建ViewRootImp对象,将ViewRootImp和DecorView关联,我们在自定义View的时候调用View.invalidate()或者View.requestLayout()要求View进行重绘的时候,在View的内部会不断的向上查找父布局,直到最外层的DecorView之后,会调用与之关联的ViewRootImp的performTraversals方法,开始真正的绘制View。View的绘制流程是从ViewRoot的performTraversals开始的,首先在performMeasure会开始DecorView的measure方法,在measure方法里会调用onMeasure方法,在onMeasure方法会对DecorView的所有子View进行测量,但是父容易怎么测量子容器的大小呢,这个时候其实是将Measure事件传递到子容易,让他自身进行测量,如此反复下去,直接子View是非容器类控件才停止测量,这样,我们的整个视图树才算测量完成。同理,performLayout和performDraw也一样、
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}