这是View的绘制流程详细的源码分析系列文章,包括ActivityThread#handleResumeActivity到ViewRootImpl#performTraversals()
performMeasure()
performLayout()
performDraw()
还有performMeasure()、performLayout()、performDraw()具体源码分析,系列文章目录如下:
从源的角度分析View的绘制流程
源码分析UI绘制三部曲之measure
源码分析UI绘制三部曲之layout(本篇)
源码分析UI绘制三部曲之draw
本篇我们分析ViewRootImpl#performLayout
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
mLayoutRequested = false;
mScrollMayChange = true;
mInLayout = true;
final View host = mView;
if (host == null) {
return;
}
...
try {
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
...
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
mInLayout = false;
}
方法的第一个参数lp是顶层布局容器的布局属性,后面两个参数mWidth,mHeight是顶层布局容器的宽高,将顶层布局容器mView赋值给host,mView为DecorView,后面接着调用host.layout()方法,并传入自己的测量宽高,继续跟进View#layout
public void layout(int l, int t, int r, int b) {
if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
int oldL &