一. 前言
在学习自定义View之前,我们首先需要了解View是怎么被一步步显示出来的。为此,我们需要了解 ViewRoot,DecorView,Window,Activity。
二. ViewRoot
1. 作用
连接器,连接 WindowManager 和 DecorView,完成 View 的绘制流程。
2. 具体描述
① ViewRoot是抽象类,ViewRootImpl是实现类。
② 与 WindowManagerService 通讯,调整窗口大小以及布局。
③ 向 DecorView 派发输事件。
④ 完成三大绘制流程:measure,layout,draw。
三. DecorView
1. 定义
顶层View,即 Android 视图树的根节点;同时也是 FrameLayout 的子类。
2. 作用
① 加载,显示布局。
② View层的事件都先经过 DecorView,再传递到 View。
3. 特别说明
DecorView内含1个竖直方向的LinearLayout,分为2部分:上 = 标题栏(titlebar)和 下 = 内容栏(content)
在Activity
中通过 setContentView()
所设置的布局文件其实是被加到内容栏之中的,成为其唯一子View(id为content的FrameLayout
)。
所以我们可以在代码中获取设置的布局:
1 | // 1. 得到content |
四. Window
1. 作用
承载器,承载着 View 的显示。
2. 具体描述
① Window类是抽象类,PhoneWindow类是实现类。
② PhoneWindow类会创建其内部类DecorView,来加载Activity中设置的布局。
③ PhoneWindow类加载布局后还需要显示,在显示的时候会获取 WindowManager 将 DecorView 传入其中。
⑤ WindowManager 内部创建了一个 ViewRootImpl 对象,负责绘制各个子View,处理事件。
五. Activity
1. 作用
控制器,控制生命周期,处理事件。
2. 特别注意
一个Activity包含一个Window,Activity不负责视图的控制,真正负责视图控制的是Window。
六. 总结
1. 创建DecorView的过程
Activity首先在Attach方法中生成了PhoneWindow的实例,然后在setContentView中直接交给Window来装载视图。先在PhoneWindow中创建了一个DecroView,其中创建的过程中可能根据Theme不同,加载不同的布局格式,例如有没有ActionBar等,然后再向content中加入子View,即Activity中设置的布局。
2. 显示DecorView的过程
当我们执行了Activity.makeVisible()方法之后,界面才对我们是可见的。wm.addView起到了重要的作用,因为其内部创建了一个ViewRootImpl对象,负责绘制显示各个子View。
1 | void makeVisible() { |
详细内容参考:自定义View-DecorView创建&显示