Android(安卓)View绘制及事件(一)屏幕的视图层级,窗口概念初识
系列推荐:
Android View绘制及事件(二)setContentView()源码,LayoutInflater加载View的过程
Android View绘制及事件(三)自定义View及View绘制流程
Android View绘制及事件(四)自定义组合控件+约束布局ConstraintLayout+自定义控件属性
Android View绘制及事件(五)View响应事件及分发过程源码详解
目录
前言
Window概念
PhoneWindow
前言
通常情况下,我们创建一个Activity时,会通过setContentView来引入布局,将界面视图展现给用户看见。那么,为什么通过setContentView()就能将布局文件加载到界面中呢?PhoneWindow是什么呢?大家先来看一张屏幕层级的图:
- PhoneWindow: Window是一个抽象对象,它的具体实现类就是PhoneWindow。
- DecorView(FrameLayout):一个应用窗口的根布局容器。
- ContentView:窗口内容的容器, setContentView就是设置它的子View。
Window概念
public abstract class Window { //设置布局文件 public abstract void setContentView(int layoutResID); public abstract void setContentView(View view); }
android.view.Window窗口抽象类。实际上,窗口是一个宏观的思想,在Android系统中,窗口是独占一个Surface实例的显示区域,每个窗口的Surface由WindowManagerService分配,当一块 Surface 显示在屏幕上时,就是用户所看到的窗口了。
WindowManagerService 添加一个窗口的过程,其实就是 WindowManagerService 为其分配一块 Surface 的过程,一块块的 Surface 在 WindowManagerService 的管理下有序的排列在屏幕上,Android 才得以呈现出多姿多彩的界面。(应用可以通过Canvas或OpenGL在其上面作画。画好之后,通过SurfaceFlinger将多块Surface按照Z-order的顺序进行混合,而后输出到FrameBuffer中,这样用户界面就得以显示。)
两个作用:
窗口主要用于 绘制各种UI元素 和 响应用户输入事件 。
三个类型:
分别是应用 Window、子 Window 和系统 Window。
- 应用类 Window 对应一个 Acitivity。
- 子 Window 不能单独存在,需要依附在特定的父 Window 中,比如常见的一些 Dialog。
- 系统 Window是需要声明权限才能创建的 Window,比如 Toast 和系统状态栏。
两个特点:
- 独立绘制,不与其它界面相互影响;
- 不会触发其它界面的输入事件;
三个核心组件:
- WindowManager.LayoutParams: 窗口的布局参数;
- Callback: 窗口的回调接口,通常由Activity实现;
- ViewTree: 窗口所承载的控件树。
PhoneWindow
PhoneWindow类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了 一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。
PhoneWindow的主要是把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作接口。另外,我们平时调用setContentView()方法设置Activity的用户界面时,实际上就完成了对所关联的PhoneWindow的ViewTree的设置
public class PhoneWindow extends Window implements MenuBuilder.Callback { private DecorView mDecor; //该对象是所有应用窗口的根视图,是FrameLayout的子类 // 是DecorView的子布局mContentRoot中的子布局,也就是DecorView孙子节点 private ViewGroup mContentParent; //设置标题 @Override public void setTitle(CharSequence title) { if (mTitleView != null) { mTitleView.setText(title); } mTitle = title; } //设置背景图片 @Override public final void setBackgroundDrawable(Drawable drawable) { if (drawable != mBackgroundDrawable || mBackgroundResource != 0) { mBackgroundResource = 0; mBackgroundDrawable = drawable; if (mDecor != null) { mDecor.setWindowBackground(drawable); } } } //... }
更多相关文章
- Android(安卓)滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+
- 《Android移动应用基础教程》(Android(安卓)Studio)(第二版)黑马教程
- 在 Android(安卓)4.1上,分析 input -- android framework 部分 2
- (三)Android事件分发机制 - Activity篇
- Android之——自定义TextView
- Android中LayoutParams总结和用法
- android 按钮点击的两种方法以及长按事件
- Android(安卓)中自定义View(三)
- Android核心分析 之十-------Android(安卓)GWES之基本原理篇