Activity的setContentView()方法源码分析

一、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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值