Activity.java 调用最常用的SetContentView
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
getWIndow()由之前的分析知道是PhoneWindow这个对象,
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
这段代码中的mContentParent,就是id为com.android.internal.R.id.content的FrameLayout,之后调用mLayoutInflater.inflate(layoutResID, mContentParent);
解释1 :Inflater简单来说就是将要inflate的View的属性(包括layout_width和layout_height)解析出来设置到View里,并将这个View添加到root这个ViewGroup的列表中。同时ViewGroup将自己设置为添加View的mParent。DecorView的mParent就是ViewRootImpl在setView的时候将自己view.assignParent(this);当做DecorView的mParent。
再之后调用mContentParent.requestApplyInsets();用于请求绘制。
经过几层调用之后进入到View.java
public void requestFitSystemWindows() {
if (mParent != null) {
mParent.requestFitSystemWindows();
}
}
最终会调用到ViewRootImpl中的。
@Override
public void requestFitSystemWindows() {
checkThread();
mApplyInsetsRequested = true;
scheduleTraversals();
}
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
doTraversal()
performTraversals()
performTraversals()中
使用performMeasure() 来测量View大小。
使用performLayout()来确定View的绘制区域。
使用performDraw()来真正的绘制。
下一篇从performMeasure来学起。