UI绘制流程(2) - 布局加载及初始化

2018-11-04  本文已影响0人  可爱的灰太狼

UI绘制流程(1)- 程序启动

UI绘制流程(2) - 布局加载及初始化

在我们熟悉的oncreate()方法之中,我们往往会用setContentView()方法来设置我们的布局,那当中又是怎样实现的呢?我们通过源码一探究竟;

setContentView()点进去会走到Window这个抽象类当中。

通过对类的描述可知window实现类为PhoneWindow,在这个类中找到setContentView()方法

此时在这个类中主要做两个事情:一个是installDecor,另一个是inflate。前者是初始化DecorView(根布局),后者是将我们的布局加载到DecorView当中。那么具体过程是怎样实现的的呢?

首先我们来看一下installDecor()方法,

mDecor为decorview对象,decorview继承FrameLayout,由此可知它也是一个ViewGroup。那么decorview承担着怎样的角色呢?其实,decorview是整个ViewTree的最顶层View,主要负责装载各种View和Activity布局。mDecor通过generateDecor()方法实例化。进入到generateDecor()方法之中。

回到installDecor()方法中,接下来往下看

mContentParent:

// mDecor itself, or a child of mDecor where the contents go.(它要么是mDecor本身,要么是mDecor的子类的内容。)

进入到generateLayout(mDecor)方法中;

generateLayout方法当中,发现了在此处进行了大量的requestFeature的调用,也就是说,我们的requestFeature设置其实是在setContentView方法当中就开始了, 这也是为什么我们自己要去getWindow.requestFeature时必须在setContent之前的原因。在generateLayout方法当中接着往下看

由以上代码可以看出,该方法还是做了相当多的工作的,首先根据设置的主题样式来设置DecorView的风格,比如说有没有titlebar之类的,接着为DecorView添加子View,而这里的子View则是上面提到的mContentParent,如果上面设置了FEATURE_NO_ACTIONBAR,那么DecorView就只有mContentParent一个子View,这也解释了上面的疑问:mContentParent是DecorView本身或者是DecorView的一个子元素。我们可以通过前面提到的getWindow.requestFeature进行设置,这里就不在具体说明。默认情况下加载的是screen_simple.xml布局。我们看看布局中有什么?

通过下面这幅图就可以看出DecorView结构关系:

然后我们再回到setContentView()方法中来看inflate方法就比较容易了,就是我们的布局通过mContentParent加载到decorview容器中


通过这幅图便可以更直观的理解资源加载流程。

小结:DecorView是顶级View,内部有titlebar和contentParent两个子元素,contentParent的id是content,而我们设置的main.xml布局则是contentParent里面的一个子元素。在DecorView创建完毕后,通过setContentView方法中inflate(layoutResID, mContentParent);这里加载了我们设置的main.xml布局文件,并且设置mContentParent为main.xml的父布局。

上一篇下一篇

猜你喜欢

热点阅读