您的位置:首页 > 其它

Activity的setContentView()方法源码分析

2016-09-21 17:31 441 查看
一、Activity的setContentView()有三种实现:

1. public void setContentView(@LayoutRes int layoutResID) {

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

2. public void setContentView(View view) {

getWindow().setContentView(view);

initWindowDecorActionBar();

}

3.public void setContentView(View view, ViewGroup.LayoutParams params) {

getWindow().setContentView(view, params);

initWindowDecorActionBar();

}

getWindow()返回的是PhoneWindow,然后看PhoneWindow的setContentView的实现

二、PhoneWindow的setContentView的归结有接受两种参数的实现,一个是参数布局文件,一个是参数view,先看参数为view的实现

public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
view.setLayoutParams(params);
final Scene newScene = new Scene(mContentParent, view);
transitionTo(newScene);
} else {
mContentParent.addView(view, params);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}


先看installDecor()方法:

private void installDecor() {

if (mDecor == null) {

mDecor = generateDecor(); // mDecor = new DecorView(getContext(), -1)

mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); // 设置mDecor的属性mGroupFlags

mDecor.setIsRootNamespace(true); // 设置属性mPrivateFlags

if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {

mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);

}

}

if (mContentParent == null) {

mContentParent = generateLayout(mDecor); // 将mDecor传入,给mDecor传入来自于系统布局生成的一个View,找到系统布局中的内容容器控件赋值给mContentParent,mContentRoot指向系统布局文件生成的View

mDecor.makeOptionalFitsSystemWindows();

……

}

如果mContentParent等于null,执行 installDecor()生成了mDecor和mContentParent,否则清空mContentParent, 最后将view添加到mContentParent。

PhoneWindow的setContentView参数是View的执行流程是:先生成一个DecorView,然后往DecorView加入一个系统的布局文件生成的View,从这个View中找到内容容器控件赋值给mContentParent,最后将接收的参数view添加到mContentParent中。

三、PhoneWindow的setContentView参数为布局文件的实现

public void setContentView(int layoutResID) {
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();
}
}
区别只在于mLayoutInflater.inflate(layoutResID, mContentParent);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码