关于Window和Screen和Decor的一点疑惑
Window和Decor的对应关系(某书中截图)
PhoneWindow是Window的一个子类,每个Activity中有一个PhoneWindow对象。标题区对应的是ActionBar,内容区域对应的是content,SetContentView方法填充的部分,选择菜单区点击菜单按钮弹出的布局。这里很明显PhoneWindow不包含系统栏(Screen必然是包含的),也就是说DecorView不包含StatusBar。
我们知道getLocationOnScreen()的坐标系是相对于屏幕而言的,getLocationInWindow()的坐标系是相对于DoctorView(RootView)而言的,如果在一个Activity中,PhoneWindow(DoctorView)和Screen不是同一块区域(相差一个StatusBar),那么DecorView.getLocationOnScreen()的top值就应该是StatusBar的高度;然而实验结果打印出来的却是0.结论指向的是:DecorView应该是充满整个屏幕的,也就是说DecorView是包含StatusBar的。
那么DecorView或者PhoneWindow到底包不包含StatusBar呢?于是找到了这样一篇文章《Android DecorView浅析》作者给出的答案是 包含的。
1、DecorView为整个Window界面的最顶层View。
2、DecorView只有一个子元素为LinearLayout。
3、DecorView代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。
原文中给出的DecorView树形图(有说DecorView是一个FrameLayout,Decor是装饰的意思)
20代表的区域是TitleBar(ActionBar具体实现),只包含了一个TextView;
很多应用并不适合以上的基本界面框架,Android提供了很多接口帮助开发者突破基本的界面样式。通过Activity.requesetWindowFeature函数开发者可以设定窗口参数,改变界面的基本形态。比如,如果需要将标题栏隐藏掉,可以通过设定Window.FEATURE_NO_TITLE来实现:
/在Activity onCreate方法中/
requesetWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(v);//注意调用顺序
标题栏可以不使用ActionBar来实现,自定义标题栏方法如下:
Activity.java#onCreate()
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.custom_title);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.custom_title_1);
载入自定义titleBar后如何查找其中元素呢,其实还是findViewById就可以了,因为载入的自定义布局已经在DecorView树中了:
public View findViewById(int id) {
return getWindow().findViewById(id);
}
也就是说对于普通的Activity而已,Window区域和Screen区域和DecorView的区域是同一块区域。那么有没有特殊情况呢?那些对象有自己的Window对象了(除了Activity),这些对象绘制流程又是怎样的呢?这个大神写的很详细,知道了Window的绘制流程对于创建悬浮窗口,蒙层效果就能信手拈来。
Android的窗口机制
- Android的窗口机制是为了将用户界面的交互传递到控件中去,它采取了基于窗口Window注册的实现模式。
- 窗口机制的核心是窗口管理服务(WindowManagerService)运行在系统核心进程的一个独立线程中,负责事件的传递。
- 窗口管理服务会为每个可视窗口分配一个窗口层次(Z-order),事件被被优先传递给层次高的窗口,同时越晚添加的窗口层次越高,越容易接收都交互事件。
- 控件和窗口管理服务的双向通信连接:RootView对象通过WindowManager向窗口管理服务发送注册请求,当用户通过硬件设备与应用进行交互的时候,系统底层的驱动会将这个操作转换成事件,然后将这个事件传递给RootView,事件再进行逐级分发。
相关控件
对话框Dialog
与界面组件相同的是Dialog对象中也包含一个Window对象,负责控件树的管理和构造,界面主键和对话框只是在应用场景上略有不同。
- Dialog对象被限定了三块区域:标题区,内容区和操作区域
- 对话框对象的构造比较耗时,可能导致界面阻塞,如果需要反复使用对话框开发者只需要动态的改变对话框中的内容即可。还可以将它融入到Activity的生命周期当中。
弹窗窗口(popWindow)
与其他交互控件不同,popwindow并不包含Window对象,popwindow会自动管理其控件树和窗口管理服务的双向通信连接。由于没有Window对象的约束,控件对象可完全自定义,在呈现上更加自由,可以通过调用其setContentView来设定它的控件对象。
- 弹窗位置需要指定一个锚点对象,而且在弹窗显示之前该锚点对象已经完成了和窗口管理服务的双向通信连接。