View的绘制流程主要包括三个过程: measure(测量)、layout(布局)和 draw(绘制)。
通过看源码可以知道这个过程开始于ViewRootImpl的performTraversals方法,该方法依次调用performMeasure、performLayout和performDraw三个方法,分别完成顶级View的measure、layout和draw三大流程。
// 源码【ViewRootImpl】中的performTraversals方法
private void performTraversals() {
...
// 执行测量
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
// 执行布局
performLayout(lp, mWidth, mHeight);
...
// 执行绘制
performDraw();
...
}
- Measure过程:此过程用来测量View的宽和高。在performMeasure中会调用View的measure方法,而在measure方法中会调用onMeasure方法,对所有的子元素进行measure过程,这样就完成了一次measure过程。子元素会重复父元素的measure过程,如此反复就完成整个View树的遍历。Measure过程之后,可以通过getMeasuredWidth和getMeasuredHeight方法来获取到View测量后的宽和高。通过setMeasuredDimension方法设置测量的大小。
- Layout过程:此过程用来确定View的四个顶点的坐标和实际的View的宽和高。在performLayout中会调用layout方法,确定View的布局left, top, right, bottom四个点的坐标,从而确定它的最终宽高和摆放位置。Layout过程之后可以通过getTop, getBottom, getLeft, getRight来拿到View的四个顶点的位置,并可以通过getWidth和getHeight方法拿到View的最终的宽和高。performLayout的传递流程和performMeasure是一样的。
- Draw过程:此过程决定了View的显示。在performDraw中会调用draw方法,通过dispatchDraw来实现传递过程。只有draw方法完成以后View的内容才能显示到屏幕上。
- 绘制背景background.draw(canvas)
- 绘制自己(ondraw)
- 绘制children(dispatchDraw)
- 绘制装饰(onDrawScrollBars)
总结来说,View的绘制流程是从ViewRootImpl的performTraversals方法开始的,经过measure、layout、和draw三个过程最终将一个View绘制出来。