Activity setContentView主要流程

 我们一般在写一个Activity的时候都会有在onCreate()方法中看到这么一个方法:setContentView(),今天就以setContentView()方法开始看看这经常出现的代码端是干什么的:

1 setContentView

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setContentView(R.layout.activity_main);
    ...
}

2 getWindow().setContentView()

3 initWindowDecorActionBar()

我们点进入setContentView(),会跳转到Activity类中,在Activity中的setContenView()方法中首先通过getWindow()来获取一个Window对象,然后调用他的setContenView()方法。最后调用了initWindowDecorActionBar()方法。

    public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

2.1 setContentView

我们先看看getWindow().setContentView(layoutResID);在之前的Android_activity事件分发流程分析中也有过分析,getWindow他其实就是获取以个PhoneWindow,接下来我们来到PhoneWindow类中,看看里面是怎么实现setContentView()的:

public void setContentView(int layoutResID) {
    ...
    if (mContentParent == null) {
        installDecor();
    } 
    ...
    mLayoutInflater.inflate(layoutResID, mContentParent);
    ...
}

2.1.1 insatllDecor()

我们看上面的代码中先判断没ContentParent是否为空,[ContentParent看名字应该是contentView的parent,是ViewGroup类型,就是个container来装contentview的] 如果为空的话,就执行installDecor();mContentParent是放置窗口内容的视图。它要么是mDecor本身,要么是mDecor的子view.

我们接下来看看insatllDecor()方法里面做了些什么:

private void installDecor() {
    ...
    if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);
    }
    ...

} 

在insatllDecor()方法中,就是调用generateLayout()创建新的mContentView。接下来我们看generateLayout方法是怎么创建mContentView的:

2.1.1.1 generateLayout()

protected ViewGroup generateLayout(DecorView decor) {
    ...
    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
    ...
}

在generateLayout()方法中直接通过ID_ANDROID_CONTENT常量来获取,其中ID_ANDROID_CONTENT是XML布局文件中的主布局应具有的ID。就是此时就是加载了xml布局文件,

2.1.2 mLayoutInflater.inflate(layoutResID, mContentParent)

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {     
    return inflate(resource, root, root != null);
}
...
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean 
    attachToRoot) {
    final Resources res = getContext().getResources();
    final XmlResourceParser parser = res.getLayout(resource);
    try {
        return inflate(parser, root, attachToRoot);
    } finally {
        parser.close();
    }
}

infater的主要工作就是解析一个具体的XML资源文件来填充view层级,也就吧我们的布局XML文件实例化为其相应的view对象.然后将view对象放进mContentParent中.为接下来得显示做准备.

所以Activity要想将布局文件显示出来,需要将布局文件setContentView.这就是我们Activity中常见的代码段setContentView(R.layout.activity_main)的实现和作用

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值