欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android View绘制及事件(一)屏幕的视图层级,窗口概念初识

程序员文章站 2022-05-24 10:25:53
...

系列推荐:

Android View绘制及事件(二)setContentView()源码,LayoutInflater加载View的过程

Android View绘制及事件(三)自定义View及View绘制流程

Android View绘制及事件(四)自定义组合控件+约束布局ConstraintLayout+自定义控件属性

Android View绘制及事件(五)View响应事件及分发过程源码详解

目录

前言

Window概念

PhoneWindow


前言

通常情况下,我们创建一个Activity时,会通过setContentView来引入布局,将界面视图展现给用户看见。那么,为什么通过setContentView()就能将布局文件加载到界面中呢?PhoneWindow是什么呢?大家先来看一张屏幕层级的图:

Android View绘制及事件(一)屏幕的视图层级,窗口概念初识

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