我们在设置全屏窗口或者dialog的时候会经常看到一个getWindow,那么这个window是什么呢。
window位于/frameworks/base/core/java/android/view/Window.java,它是一个抽象类,window类可以控制顶级View的外观和行为策略,通过这个我们可以联想到,肯定还有一个东西(可能叫xxxWindow)继承了window这个抽象类,并且实现了它的所有抽象方法,正如它的名字一样,这些抽象方法是用来画一个窗口。
这个时候我们接着往下看,果然有一个东西叫PhoneWindow(抽象类window的唯一实现),证实了我们上面的猜想,这个东西可以看做是window的实现类。源码这个理不摆了,简单描述一下这个phoneWindow。
这个类里有一个特别重要的view叫DecorView。
DecorView是android所有Activity的根View。(DecorView是PhoneWindow里的一个对象),而DecorView本身是PhoneWindow的内部类,那么DecorView到底是个什么东西呢,不可能是石头里蹦出来的吧(android里界面的东西,追溯根源,无外乎就是会找到一些View,ViewGroup,Window),这时候不要害怕啊,去找,我们发现果然DecorView继承自FrameLayout(FrameLayout继承自ViewGroup,我们的猜想没错。)然后系统就对这个FrameLayout进行扩展,添加了点我们看到的activity里的标题栏啊什么的。
思路到这里就清楚了,PhoneWindow操作一些API在这个DecorView(也就是FrameLayout)上画了一下东西,就画成了我们看到的Activity。至于怎么画的,这又是另一个关于android源码的大问题了。这里为了不能跑题,不做讨论。
END....
好了,现在我们知道了,最外层铁定是一个FrameLayout了。
接下来要放两张图。
结构已经很清晰了,DecorView里面有一个LinearLayout,然后LinearLayout从上到依次可能会放状态栏,内容布局,虚拟键盘。
我们XML里面的布局文件就是放在这个内容布局(FrameLayout)里xml文件,所以我们自己写的布局的父布局一定是这个DecorView。
获取DecorView:
activity.findViewById(android.R.id.content);
获取我们的xml布局:
activity.findViewById(android.R.id.content).getChildAt(0);
看一个老生常谈的问题就是我们经常用的
findViewById和setContentView到底是什么意思。
public void setContentView(int layoutResID){
getWindow().setContentView(layoutResID);
initActionBar();
}
public Window getWindow(){
return mWindow;//Window对象,本质上是一个PhoneWindow对象
}