在Activity中调用setContentView(R.layout.activity_main)方法,就会进入AppCompatActivity中的setContentView(@LayoutRes int layoutResID)
public void setContentView(@LayoutRes int layoutResID) {
this.getDelegate().setContentView(layoutResID);
}
首先分析AppCompatActivity中的this.getDelegate()
@NonNull
public AppCompatDelegate getDelegate() {
if (this.mDelegate == null) {
this.mDelegate = AppCompatDelegate.create(this, this);
}
return this.mDelegate;
}
在getDelegate()方法中通过AppCompatDelegate.create(this, this);创建了AppCompatDelegate 的实例mDelegate,接下来看AppCompatDelegate.create(this, this)
public static AppCompatDelegate create(Activity activity,
AppCompatCallback callback) {
return new AppCompatDelegateImpl(activity, activity.getWindow(), callback);
}
create方法返回的是AppCompatDelegateImpl对象,那Activity中的setContentView()方法最终会调用AppCompatDelegateImpl类中的setContentView()方法,如下所示:
public void setContentView(int resId) {
this.ensureSubDecor();
ViewGroup contentParent = (ViewGroup)this.mSubDecor.findViewById(16908290);
contentParent.removeAllViews();
LayoutInflater.from(this.mContext).inflate(resId, contentParent);
this.mOriginalWindowCallback.onContentChanged();
}
到这里就调用了LayoutInflater.from(this.mContext).inflate(resId, contentParent);
通过inflate方法最终将R.layout.activity_main加入到contentParent上;
inflate(resId, contentParent)方法最终都会调用到 inflate(parser, root, root != null);
接下来看inflate方法:
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");
...
try {
// Look for the root node.
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
// Empty
}
...
if (TAG_MERGE.equals(name)) {
...
} else {
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
...
// Create layout params that match root, if supplied
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
...
// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
if (root != null && attachToRoot) {
root.addView(temp, params);
}
// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
result = temp;
}
}
...
return result;
}
通过对上面代码分析:
- final View temp = createViewFromTag(root, name, inflaterContext, attrs);
- 由于root != null; 拿到布局参数params = root.generateLayoutParams(attrs);
- root != null && attachToRoot 为true;执行如下代码,将R.layout.activity_main加入到了DecorView上。
if (root != null && attachToRoot) {
root.addView(temp, params);
}