ViewRootImpl类的performTraversals()中组装了初始的MeasureSpec
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
……
performMeasure();
……
performLayout();
……
performDraw();
getRootMeasureSpec():
/**
* Figures out the measure spec for the root view in a window based on it's
* layout params.
*
* @param windowSize The available width or height of the window
*
* @param rootDimension The layout params for one dimension (width or height) of the window.
*
* @return The measure spec to use to measure the root view.
*/
private static int getRootMeasureSpec(int windowSize, int rootDimension) {
int measureSpec;
switch (rootDimension) {
case ViewGroup.LayoutParams.MATCH_PARENT:
// Window can't resize. Force root view to be windowSize.
measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
break;
case ViewGroup.LayoutParams.WRAP_CONTENT:
// Window can resize. Set max size for root view.
measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
break;
default:
// Window wants to be an exact size. Force root view to be that size.
measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
break;
}
return measureSpec;
}
performMeasure()会调用View的measure():
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);
}
}
performLayout()会调用View的layout(),performDraw()会调用drawSoftware(),drawSoftware()中调用到mView.draw(canvas);
draw()中调用到onDraw()
本文详细解析了ViewRootImpl中的performTraversals方法,包括如何通过getRootMeasureSpec确定MeasureSpec,进而进行视图的测量、布局和绘制过程。

被折叠的 条评论
为什么被折叠?



