系列推荐:

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);              }          }      }      //...      }  

更多相关文章

  1. Android(安卓)滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+
  2. 《Android移动应用基础教程》(Android(安卓)Studio)(第二版)黑马教程
  3. 在 Android(安卓)4.1上,分析 input -- android framework 部分 2
  4. (三)Android事件分发机制 - Activity篇
  5. Android之——自定义TextView
  6. Android中LayoutParams总结和用法
  7. android 按钮点击的两种方法以及长按事件
  8. Android(安卓)中自定义View(三)
  9. Android核心分析 之十-------Android(安卓)GWES之基本原理篇

随机推荐

  1. android自学笔记(1):android简介
  2. Android开发规范(编码+性能+UI)
  3. 用Android(安卓)Studio 运行ndk 程序
  4. Android之布局属性重点
  5. Android(安卓)11适配指南之系统相机拍照
  6. Android(安卓)Fresco图片加载库基础使用
  7. Android应用程序与SurfaceFlinger服务的
  8. Android的webview做web应用研究
  9. 我做了五年Android应用层开发,凭什么比一
  10. Android对Linux内核的改动你知道多少