Android控件架构
1.什么是View?
View是Android中所有控件的基类。View是界面层的控件的一种抽象,它代表了一个控件。在Android中每个控件都会在界面中占得一块矩形的区域。在Android中控件被分为两类:View和ViewGroup。ViewGroup控件作为父控件可以包含多个View控件,并管理它包含的View控件。通过ViewGroup,整个界面上的控件形成了一个树形结构,这几件事我们常说的控件树,上层控件负责下层子控件的测量和绘制,并传递交互事件。
2.所谓的树结构
ViewGroup,顾名思义,它是控件组。但是,在Android的设计中,ViewGroup也是继承自View的,这也就意味着View本身就是可以是单个控件也可以是由多个控件组成的一组控件。通过这种关系就形成了View树的结构。-- Android开发艺术探索
3.findViewById()是如何找到元素的?
我们使用findViewById()方法,就是在控件树种以树的深度优先遍历来查找对应元素。在每个控件树的顶部都有一个ViewParent对象,它就是整棵树的控制核心,所有的交互管理事件都由它来统一调度和分配,从而可以对整个视图进行整体控制。
4.View树结构,和UI界面架构图
图来自《Android群英传》
View树结构&UI界面架构图.png
5.剖析UI界面架构图
正如图3.2所示,每个Activity都包含一个Window对象,在Android中Window对象通过由PhoneWindow 来实现。
PhoneWindow将一个DecorView设置为整个应用窗口的根View。
DecorView作为窗口界面的顶层视图,封装了一些窗口操作的通用方法。可以说,DecorView将要显示的具体内容呈现在了PhoneWindow上,这里面所有的View 监听事件,都通过WindowManagerService 来接收,并通过Activity对象来回调相应的onClickListener。
在显示上,一般情况下DecorView内部会包含一个垂直方向的LinearLayout,将屏幕分成两个部分,一个是TitleView,一个是ContentView,现在知道为啥子我们设置布局的时候是setContentView(R.layout.activity_main) 了吧。 这个我们非常亲密的布局——ContentView,它是一个ID为android.R.id.content的FrameLayout,我们的布局文件layout.activity_main就是设置在这样一个FrameLayout里面的。
知道了上面的这些之后,介绍一下标准视图树。
6.almost标准视图树
为什么是almost标准视图树,因为Android版本对AndroidUI会变动啊,可能某个时候这就不适用了。
almost标准视图树.png
上面的就是最常用的布局,上面TitleBar/ActionBar(这里先不说ToolBar的事),下面Content,(在TitleBar的情况下)如果用户使用requestWindowFeature(Window.FEATURE_NO_TITLE)设置全屏,那么就只剩下Content了。并且requestWindowFeature(Window.FEATURE_NO_TITLE)要早setContentView之前调用,为啥?因为Content要占用TitleBar的位置。
而在代码中,当程序在onCreate()中调用setContentView()方法后,ActivityManagerService会回调onResume()方法,此时系统才会把整个DecorView添加到PhoneWindow中,并让内容显示出来,从而完成界面的绘制。
8.补充知识:TitleBar和ActionBar的区别
因为之前的内容说道了TitleBar,TitleBar是个老旧的东西,所以这两年才学Android的朋友可能没听到这玩意。下面补充一下TitleBar的常用的问题。
主要是说说隐藏actionBar和titileBar的问题
隐藏ActionBar和TitleBar方式很多,想了解的看这位网友写的blog
先来看个例子:
public class MainActivity extends AppCompatActivity {
Button mBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
}
运行之后发现,上面的"TitleBar"没有消失,是不是很生气,是不是想骂我骗子。客官不可以,您息怒。听我娓娓道来。
我们来看看ActionBar来自何方。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
// requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
// 我们command+点击 getSupportActionBar(),发现这个方法是AppCompatActivity类中的。
// 同样的方式你会发现requestWindowFeature()是Activity类的。
// 所以,现在你是不是该明白点什么。
下面说TitleBar与ActionBar的区别:
i. 两者activity继承的类不一样,actionbar继承AppCompatActivity, titlebar继承Activity,如果搞混了继承的类的话,会导致上述隐藏相应控件失效。
ii. TitleBar,也就是标题栏,它紧挨在状态栏的下面,正常情况下它的布局和主题样式都是使用系统定义好的,且默认情况下只显示图标和文本。
iii. ActionBar,也就是操作栏,它是Android3.0以后引入SDK的,通过它去取代之前标题栏,它和标题栏一样紧挨状态栏的下面,它可以放入按钮,或下拉式的按钮.可以有文字,logo等信息.还可以设置返回按钮等信息。
参考资料:
developer.android.com
Android群英传
Android开发艺术探索
下一篇文章准备写Android世界的坐标系