一、Activity的窗口理解
每一个 Activity 都持有一个 Window 对象,但是 Window 是一个抽象类,这里 Android 为 Window 提供了唯一的实现类 PhoneWindow。也就是说 Activity 中的 window 实例就是一个 PhoneWindow 对象。
但是 PhoneWindow 终究是 Window,它并不具备多少 View 相关的能力。
不过 PhoneWindow 中持有一个 Android 中非常重要的一个 View 对象 DecorView.
现在的关系就很明确了,每一个 Activity 持有一个 PhoneWindow 的对象,而一个 PhoneWindow 对象持有一个 DecorView 的实例,所以 Activity 中 View 相关的操作其实大都是通过 DecorView 来完成,DecorView包含TitleView(ActionBar)和ContentView。
decorView 本身是一个 FrameLayout,当 decorView 接受到来自 Activity 传递过来的布局 id 后,通过 inflater(布局填充器),把布局资源 id 转换为一个 View,然后把这个布局 View 添加在自身中。
总结:其实可以看到上面这个跟 View 操作相关的分析过程中,Activity、以及 Activity 的成员变量 mWindow 什么也没干,他们拿到参数都第一时间都是外抛,最终都会抛给 mWindow 的 decorView 去做具体的逻辑。
二、遍历View的子元素
DecorView包含TitleView(ActionBar)和ContentView,通过以下方法能够遍历所有的子元素:
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
View view = this.getWindow().getDecorView();
//遍历View的子元素
List<View> viewList = getAllChildViews(view);
}
private List<View> getAllChildViews(View view) {
List<View> allchildren = new ArrayList<View>();
if (view instanceof ViewGroup) {
ViewGroup vp = (ViewGroup) view;
for (int i = 0; i < vp.getChildCount(); i++) {
View viewchild = vp.getChildAt(i);
allchildren.add(viewchild);
//再次调用本身(递归)
allchildren.addAll(getAllChildViews(viewchild));
}
}
return allchildren;
}