viewrootimpl performLayout源码解读
时间: 2023-10-10 22:06:05 浏览: 34
ViewRootImpl是Android系统中负责实现View树的绘制和事件分发的核心类。performLayout方法是ViewRootImpl中非常重要的一个方法,它主要负责对View树进行布局的计算和绘制。
下面对performLayout方法的源码进行解读:
```java
void performLayout(final WindowManager.LayoutParams attrs, final int desiredWindowWidth, final int desiredWindowHeight) {
//...省略部分代码
if (mLayoutRequested) {
performLayout();
}
}
void performLayout() {
if (mView == null) {
return;
}
//...省略部分代码
mLayoutRequested = false;
mScrollMayChange = true;
long frameTime = System.nanoTime();
if (!mLastInCompatMode || mForceNextWindowRelayout) {
mForceNextWindowRelayout = false;
boolean windowSizeMayChange = measureHierarchy(mView, lp, res, desiredWindowWidth, desiredWindowHeight);
if (windowSizeMayChange) {
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
}
} else {
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
}
//...省略部分代码
}
```
performLayout方法首先会判断mLayoutRequested标志位是否被设置,如果设置了就调用performLayout()方法进行布局。performLayout()方法中,首先判断mView是否为null,如果为null则直接返回。接着会进行一些变量的初始化操作,然后会调用measureHierarchy()方法对View树进行测量,如果测量结果表明窗口大小可能会发生变化,则会调用performLayout()方法重新进行布局。
接下来我们看一下measureHierarchy()方法的源码:
```java
private boolean measureHierarchy(View host, WindowManager.LayoutParams lp,
Resources res, int desiredWindowWidth, int desiredWindowHeight) {
host.measure(getRootMeasureSpec(desiredWindowWidth, lp.width),
getRootMeasureSpec(desiredWindowHeight, lp.height));
final boolean windowSizeMayChange = host.isLayoutRequested();
if (windowSizeMayChange) {
// ...省略部分代码
}
return windowSizeMayChange;
}
```
measureHierarchy()方法中,首先会调用View的measure()方法进行测量,测量的宽度和高度分别通过getRootMeasureSpec()方法获取。如果View的布局请求被设置了,说明窗口的大小可能会发生变化,此时返回true。如果窗口大小可能会发生变化,则会在performLayout()方法中重新进行布局。
最后,我们来看一下performLayout()方法的源码:
```java
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
//...省略部分代码
final int l = frame.left + (frame.right - frame.left - mWidth) / 2 + lp.x;
final int t = frame.top + (frame.bottom - frame.top - mHeight) / 2 + lp.y;
//...省略部分代码
if (mSurfaceHolder != null) {
mSurfaceHolder.setFixedSize(mWinFrame.width(), mWinFrame.height());
}
//...省略部分代码
}
```
performLayout()方法中,首先会计算出View的左上角坐标,然后会调用setFixedSize()方法设置SurfaceView的大小,最后调用scheduleTraversals()方法开始绘制View树。至此,performLayout()方法的工作就完成了。
综上所述,performLayout()方法主要负责对View树进行布局的计算和绘制,它是ViewRootImpl的核心方法之一。在View的使用过程中,我们可以通过调用requestLayout()方法来重新请求布局,从而触发performLayout()方法重新进行布局。