Activity.java
public void setContentView(@LayoutRes int layoutResID) {
//activity的setContentView
getWindow().setContentView(layoutResID);
}
点击setContentView
//发现是抽象方法.表示有子类实现了这个方法.
public abstract void setContentView(@LayoutRes int layoutResID);
getWindow调用的setContentView.我们来看一下getWindow()方法.
public Window getWindow() {
return mWindow;
}
看哪里实例化.找到了实例化的地方.看到PhoneWindow.我们找到PhoneWindow这个类看它实现的setContentView方法
mWindow = new PhoneWindow(this, window, activityConfigCallback);
phoneWindow.java
查看phoneWindow的setContentView方法.
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
// 如果mContentParent 等于空,调用installDecor();生成DecorView
installDecor();
}
// 把我们自己的布局layoutId加入到mContentParent,我们set进来的布局原来是放在这里面
mLayoutInflater.inflate(layoutResID, mContentParent);
}
查看installDecor方法
private void installDecor() {
if (mDecor == null) {
//如果mDecor 为空,创建DecorView
mDecor = generateDecor();
}
if (mContentParent == null) {
//生成Layout
mContentParent = generateLayout(mDecor);
}
}
//创建DecorView
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
//DecorView是一个FrameLayout
private final class DecorView extends FrameLayout
/**
* The ID that the main layout in the XML layout file should have.
*/
public static final int ID_ANDROID_CONTENT = com.android.internal.R.id.content
protected ViewGroup generateLayout(DecorView decor) {
// Inflate the window decor.
int layoutResource;
//做了一系列判断,去加载系统Layout资源
layoutResource = R.layout.screen_simple;
//解析实例化系统的布局
View in = mLayoutInflater.inflate(layoutResource, null);
//把系统的布局加入到DecorView中.
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
//找一个叫做anroid.R.id.context的FrameLayout
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
//返回叫做anroid.R.id.context的FrameLayout
return contentParent;
}
screen_simple.xml
系统布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<ViewStub android:id="@+id/action_mode_bar_stub"
android:inflatedId="@+id/action_mode_bar"
android:layout="@layout/action_mode_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarTheme" />
<FrameLayout
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundInsidePadding="false"
android:foregroundGravity="fill_horizontal|top"
android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>
setContentView() 系统到底把我们的布局加到哪里去了。我先用文字总结一下,然后去画一张图:
1.Activity里面设置setContentView(),我们的布局显示主要是通过PhoneWindow,PhoneWindow获取实例化一个DecorView。
2.实例化DecorView,然后做一系列的判断然后去解析系统的资源layoutId文件,把它解析加载到DecorView,资源layout里面有一个View的id是android.R.id.content.
3.我们自己通过setContentView设置的布局id其实是解析到mParentContent里面的,也就是那个id叫做android.R.id.content的FarmeLayout。
网友评论