简介
这篇文章继续就上一篇文章【View】- setContentView方法和UI绘制流程(源码分析)中performLayout方法进行讲解,了解UI绘制的布局过程。如果想了解测量流程,请查看【view】- 测量流程。
performLayout
读过【View】- setContentView方法和UI绘制流程(源码分析)应该知道,performLayout中的mView是顶层布局DecorView。
所以首先还是调用DecorView的layout方法。而DecorView没有实现layout方法,其父类ViewGroup实现了,然后调用父类View的layout(int l, int t, int r, int b)方法。
在layout会调用 onLayout(changed, l, t, r, b)方法,先看一下DecorView中的onLayout方法。
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 = mLeft;
int oldT = mTop;
int oldB = mBottom;
int oldR = mRight;
//这里调用了setFrame进行初始化mLeft,mRight,mTop,mBottom这四个值
boolean changed = isLayoutModeOptical(mParent) ?
setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
...
}
...
}
setFrame(int left, int top, int right, int bottom)对上下左右四个点坐标进行初始化。setFrame在进行初始化的时候会对比上一次是否一致,若一致则不会在此进行,若是一致,则会使我们旧的信息直接失效invalidate(sizeChanged)。
调用父类onLayout方法
super.onLayout(changed, left, top, right, bottom);
FrameLayout中的onLayout方法,调用layoutChildren(int left, int top, int right, int bottom, boolean forceLeftGravity) 方法。layoutChildren经过一系列的计算,然后遍历DecorView所以子View,然后调用子View的layout方法,根据前面将的,最终调用子View的onLayout方法,并把开始布局的位置参数传递给子View。