一个软件程序精美的界面是要怎么样实现的呢?针对于这个问题,下面我将通过 Java 中的 Swing 类相关 Layout 布局的知识,来回答这个问题。
一、View layout方法
首先,还是从ViewRootImpl
说起,界面的绘制会触发performMeasure、performLayout
方法,而在performLayout
方法中就会调用mView的layout
方法开始一层层View的布局工作。
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
final View host = mView;
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
}
mView
我们都知道了,就是顶层View——DecorView
,那么就进去看看DecorView
的layout方法:
不好意思,DecorView中并没有layout方法...
所以,我们直接看看View的layout
方法:
public void layout(int l, int t, int r, int b) {
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);
}
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
- 首先,方法传入了四个参数,分别代表view的
左、上、下、右
四个值。 - 然后通过
setOpticalFrame
方法或者setFrame
方法判断布局参数是否改变。
具体判断过程就是通过老的上下左右值和新的上下左右值进行比较,逻辑就在setFrame
方法中:
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 our old position
invalidate(sizeChanged);
mLeft = left;
mTop = top;
mRight = right