关于Android setContentView
1.setContentView 方法,从下面的代码可以看出,真正setContentView的是Window,而这个Window的实现就是PhoneWindow
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initActionBar();
}
2,继续看 getWindow().setContentView(layoutResID)方法,如下
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
//我们自己定义的Activity的布局文件被填充到mContentParent中
mLayoutInflater.inflate(layoutResID, mContentParent);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
3.从mLayoutInflater.inflate(layoutResID, mContentParent);看出我们自己定义的Activity的布局文件被填充到mContentParent中,那么mContentParent是什么呢, 接着看installDecor();,如下
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
//...
}
if (mContentParent == null) {
//这里生成了包裹我们布局文件的mContentParent
mContentParent = generateLayout(mDecor);
mTitleView = (TextView) findViewById(com.android.internal.R.id.title);
if (mTitleView != null) {
} else {
mActionBar=(ActionBarView)findViewById(com.android.internal.R.id.action_bar);
if (mActionBar != null) {
}
}
}
}
public View findViewById(int id) {
return getDecorView().findViewById(id);
}
public DecorView(Context context, int featureId) {
super(context);
mFeatureId = featureId;
}
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
4.generateLayout(mDecor)方法
protected ViewGroup generateLayout(DecorView decor) {
// Apply data from current theme.
TypedArray a = getWindowStyle();
//...Window_windowIsFloating,Window_windowNoTitle,Window_windowActionBar...
if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {
requestFeature(FEATURE_NO_TITLE);
}
//...
if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {
setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
}
WindowManager.LayoutParams params = getAttributes();
// Inflate the window decor.
int layoutResource;
int features = getLocalFeatures();
// System.out.println("Features: 0x" + Integer.toHexString(features));
if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(
com.android.internal.R.attr.dialogTitleIconsDecorLayout, res, true);
layoutResource = res.resourceId;
} else {
layoutResource = com.android.internal.R.layout.screen_title_icons;
}
// XXX Remove this once action bar supports these features.
removeFeature(FEATURE_ACTION_BAR);
// System.out.println("Title Icons!");
} else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0
&& (features & (1 << FEATURE_ACTION_BAR)) == 0) {
// Special case for a window with only a progress bar (and title).
// XXX Need to have a no-title version of embedded windows.
layoutResource = com.android.internal.R.layout.screen_progress;
// System.out.println("Progress!");
} else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {
// Special case for a window with a custom title.
// If the window is floating, we need a dialog layout
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(
com.android.internal.R.attr.dialogCustomTitleDecorLayout, res, true);
layoutResource = res.resourceId;
} else {
layoutResource = com.android.internal.R.layout.screen_custom_title;
}
// XXX Remove this once action bar supports these features.
removeFeature(FEATURE_ACTION_BAR);
} else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {
// If no other features and not embedded, only need a title.
// If the window is floating, we need a dialog layout
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(
com.android.internal.R.attr.dialogTitleDecorLayout, res, true);
layoutResource = res.resourceId;
} else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
layoutResource = com.android.internal.R.layout.screen_action_bar;
} else {
layoutResource = com.android.internal.R.layout.screen_title;
}
// System.out.println("Title!");
} else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
layoutResource = com.android.internal.R.layout.screen_simple_overlay_action_mode;
} else {
// Embedded, so no decoration is needed.
layoutResource = com.android.internal.R.layout.screen_simple;
// System.out.println("Simple!");
}
View in = mLayoutInflater.inflate(layoutResource, null);
//从这里可以看出decorView添加了layoutResource填充成的View,这个View
//就是系统预制的布局文件也可以理解为“模板布局文件”,这个文件里面有个id为ID_ANDROID_CONTENT
//的FrameLayout,我们自定义的Activity的布局文件填充成View后就添加到这个FrameLayout了
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
//或者id为ID_ANDROID_CONTENT的控件,其实就是FrameLayout
//从这里可以知道,contentParent就是为id为ID_ANDROID_CONTENT的FrameLayout
//我们的布局文件就是添加到这个容器里面了
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
//...
return contentParent;
}
参考博客:
http://blog.csdn.net/lmj623565791/article/details/41894125