1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| // 计算View的四个顶点为孩子(left、top、right、bottom) 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; } // 保存上一次View的四个位置 int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; // 设置当前视图View的l、t、r、b位置,及判断布局是否有改变 boolean changed = isLayoutModeOptical(mParent) ? setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b); // View大小 或者 位置发生变化 则重新布局View if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) { // 1. 对于单一View,onLayout是一个空实现 // 2. 对于ViewGroup,因为位置的确定与布局有关,所以onLayout是一个抽象方法,需要重写实现 onLayout(changed, l, t, r, b); ... } ... }
// 通过传入的4个顶点位置设置View的四个顶点位置 ,返回位置是否变化 protected boolean setFrame(int left, int top, int right, int bottom) { boolean changed = false; // 是否改变 if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { changed = true; // Remember our drawn bit int drawn = mPrivateFlags & PFLAG_DRAWN; int oldWidth = mRight - mLeft; int oldHeight = mBottom - mTop; int newWidth = right - left; int newHeight = bottom - top; boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight); // 位置变化,执行invalidate invalidate(sizeChanged); // 设置新的顶点位置 mLeft = left; mTop = top; mRight = right; mBottom = bottom; mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); ...
} return changed; }
// 单一View在layout已经确定了位置,所以onLayout空实现 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
|