activity界面架构即activity视图层结构
2015-12-16 17:14
351 查看
之前看郭霖文章讲LayoutInflater 的时候,有讲到在加载的layout中最外层布局设置绝对宽高是无效的。我们在Activity中setContenView()的时候,其实质也是利用的LayoutIflater 加载的Activity布局。而这时设置的绝对宽高是有效的。是因为在setContentView()的时候,系统会默认在外面包一层FrameLayout。郭霖还用log把当前Activity布局的父布局打印了出来。
当时看到这个心里面就很疑问,为什么要在外面默认加一层父布局呢?后来看到Android群英传,才知道,原来根本不是什么默认加了一层父布局,而是和Activity界面的架构有关。下面就先说下Activity的视图架构。
先上图:
![](https://img-blog.csdn.net/20151216174041873?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
就是这张图,Activity的UI架构图(图是网上找的)。从图中可以清楚的看出,Activity的UI结构。其实每个Activity中都包含一个Window对象,通常,Android中的Window是由PhoneWindow实现的。而PhoneWindow又将一个DecorView设置为整个窗口的根View(DecorView是一个ViewGroup)。
DecorView里面又有两个View,一个是用作title或者导航栏的,另外一个是ID为content的FrameLayout用来装我们加写的Xml文件布局的View。这也就是我们给Activity设置布局的方法命名为setContentView的原因。我们如果在AndroidStadio中创建一个Activity,setContentView,我们的加载布局的只是title下面那一块矩形区域,然后上面一般是显示我们App名称的一个title。
在我第一次写一个Activity的时候,就很想把Activity上面的title去掉。网上终于查到用requestWindowFeature(Window.FEATURE_NO_TITLE);但是没效果。当时那个郁闷,于是又继续搜,终于给我发现了,原来requestWindowFeature(Window.FEATURE_NO_TITLE)这个方法要在setContentView,之前调用。于是照做了,靠谱。然而当时并不懂为什么要这么搞,现在就很明显了。View的加载肯定是现有父布局,然后才加载子view的嘛,这个从很多方面都可以看出来,比如findViewById时要用根布局或者父布局的findViewById方法,还有一些子View定义在父布局里的属性,像居中,距离边框多远之类的,没有父布局的话,怎么搞。明白了这个,我们就很容易理解了。当我们setContentView之后,我们的Xml文件都加载了,那他的父布局的FrameLayout肯定加载好了,和他同深度的title的那个View也加载好了,所以再去设置Window.FEATURE_NO_TITLE属性也就没用了,所以必须把设置窗口属性的代码放在setContentView之前。窗口在setContentView之前把title干掉,然后整个父布局里就剩下setContentView里的布局了,自然占满整个窗口了。
下面看Activity的视图树:
![](https://img-blog.csdn.net/20160504104902295)
不再反复说了,总结下:Activity不管视图显示方面的事,而是把视图管理交给了Window,Window是一个抽象类,他的实现是PhoneWindow。也就是Activity里面有个属性是一个PhoneWindow。然后这个PhoneWindow又是有一个根布局ViewGroup叫做DecorView,这个DecorView又有两个ViewGroup,就如上图了。。。其实Android就是通过这种委托思想来处理视图显示的事的。当然至于onResume等Activity生命周期变化时什么时机这些View显示,什么时机不可见,不是本篇讨论的内容了。上面只是说明要显示时,加载的顺序,和加载出来以后的视图结构。
结束,拜拜!
当时看到这个心里面就很疑问,为什么要在外面默认加一层父布局呢?后来看到Android群英传,才知道,原来根本不是什么默认加了一层父布局,而是和Activity界面的架构有关。下面就先说下Activity的视图架构。
先上图:
就是这张图,Activity的UI架构图(图是网上找的)。从图中可以清楚的看出,Activity的UI结构。其实每个Activity中都包含一个Window对象,通常,Android中的Window是由PhoneWindow实现的。而PhoneWindow又将一个DecorView设置为整个窗口的根View(DecorView是一个ViewGroup)。
DecorView里面又有两个View,一个是用作title或者导航栏的,另外一个是ID为content的FrameLayout用来装我们加写的Xml文件布局的View。这也就是我们给Activity设置布局的方法命名为setContentView的原因。我们如果在AndroidStadio中创建一个Activity,setContentView,我们的加载布局的只是title下面那一块矩形区域,然后上面一般是显示我们App名称的一个title。
在我第一次写一个Activity的时候,就很想把Activity上面的title去掉。网上终于查到用requestWindowFeature(Window.FEATURE_NO_TITLE);但是没效果。当时那个郁闷,于是又继续搜,终于给我发现了,原来requestWindowFeature(Window.FEATURE_NO_TITLE)这个方法要在setContentView,之前调用。于是照做了,靠谱。然而当时并不懂为什么要这么搞,现在就很明显了。View的加载肯定是现有父布局,然后才加载子view的嘛,这个从很多方面都可以看出来,比如findViewById时要用根布局或者父布局的findViewById方法,还有一些子View定义在父布局里的属性,像居中,距离边框多远之类的,没有父布局的话,怎么搞。明白了这个,我们就很容易理解了。当我们setContentView之后,我们的Xml文件都加载了,那他的父布局的FrameLayout肯定加载好了,和他同深度的title的那个View也加载好了,所以再去设置Window.FEATURE_NO_TITLE属性也就没用了,所以必须把设置窗口属性的代码放在setContentView之前。窗口在setContentView之前把title干掉,然后整个父布局里就剩下setContentView里的布局了,自然占满整个窗口了。
下面看Activity的视图树:
不再反复说了,总结下:Activity不管视图显示方面的事,而是把视图管理交给了Window,Window是一个抽象类,他的实现是PhoneWindow。也就是Activity里面有个属性是一个PhoneWindow。然后这个PhoneWindow又是有一个根布局ViewGroup叫做DecorView,这个DecorView又有两个ViewGroup,就如上图了。。。其实Android就是通过这种委托思想来处理视图显示的事的。当然至于onResume等Activity生命周期变化时什么时机这些View显示,什么时机不可见,不是本篇讨论的内容了。上面只是说明要显示时,加载的顺序,和加载出来以后的视图结构。
结束,拜拜!
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories