博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android GUI之Window、WindowManager
阅读量:5743 次
发布时间:2019-06-18

本文共 6036 字,大约阅读时间需要 20 分钟。

  通过前几篇的文章(查看系列文章: ),我们清楚了Activity实际上是将视图的创建和显示交给了Window对象进行了处理并分析了视图的测量、布局及绘制过程。本篇文章将继续详细分析Window及WindowManger的作用。

  首先,我们将通过下图弄清楚他们之间的关系。

  通过前几篇的文章,我们清楚了Activity实际上是将视图的创建和显示交给了Window对象进行了处理并分析了视图的测量、布局及绘制过程。本篇文章将继续详细分析Window及WindowManger的作用。

  首先,我们将通过下图弄清楚他们之间的关系。

/** Flag for the "options panel" feature.  This is enabled by default. */    public static final int FEATURE_OPTIONS_PANEL = 0;    /** Flag for the "no title" feature, turning off the title at the top     *  of the screen. */    public static final int FEATURE_NO_TITLE = 1;   //无标题栏    /** Flag for the progress indicator feature */    public static final int FEATURE_PROGRESS = 2;  //在标题栏上添加加载进度条    /** Flag for having an icon on the left side of the title bar */    public static final int FEATURE_LEFT_ICON = 3;    /** Flag for having an icon on the right side of the title bar */    public static final int FEATURE_RIGHT_ICON = 4;    /** Flag for indeterminate progress */    public static final int FEATURE_INDETERMINATE_PROGRESS = 5;    /** Flag for the context menu.  This is enabled by default. */    public static final int FEATURE_CONTEXT_MENU = 6;    /** Flag for custom title. You cannot combine this feature with other title features. */public static final int FEATURE_CUSTOM_TITLE = 7;public static final int FEATURE_ACTION_BAR = 8;public static final int FEATURE_ACTION_BAR_OVERLAY = 9;public static final int FEATURE_ACTION_MODE_OVERLAY = 10;public static final int FEATURE_MAX = FEATURE_ACTION_MODE_OVERLAY;    /** Flag for setting the progress bar's visibility to VISIBLE */    public static final int PROGRESS_VISIBILITY_ON = -1;    /** Flag for setting the progress bar's visibility to GONE */    public static final int PROGRESS_VISIBILITY_OFF = -2;    /** Flag for setting the progress bar's indeterminate mode on */    public static final int PROGRESS_INDETERMINATE_ON = -3;    /** Flag for setting the progress bar's indeterminate mode off */    public static final int PROGRESS_INDETERMINATE_OFF = -4;    /** Starting value for the (primary) progress */    public static final int PROGRESS_START = 0;    /** Ending value for the (primary) progress */    public static final int PROGRESS_END = 10000;    /** Lowest possible value for the secondary progress */    public static final int PROGRESS_SECONDARY_START = 20000;    /** Highest possible value for the secondary progress */public static final int PROGRESS_SECONDARY_END = 30000;

  那么如何应用这些窗口特征呢?在Activity中,我们可以调用方法requestWindowFeature,实际此方法是调用了Window中的requestFeature的方法,方法原型如下:

public boolean requestFeature(int featureId) {        final int flag = 1<

  注意此方法必须在setContentView方法之前调用才有效,一旦应用了这些窗口特征后续不可更改。

  在window中定义了一个CallBack接口,此接口中一定了一系列的时间回调方法,用于处理UI的各种事件,如按键事件、触摸事件、轨迹球、Accessibility事件、菜单事件等等。比如Activity就实现了此接口。关于事件这块的内容,我们后面专门做分析研究。

  在window中还定义了WindowManager,从字面上可以理解为窗口管理器,实际上它并不是真正的窗口管理器,WindowManager Service才是Android中真正意义上的窗口管理器。实际上Window内的WindowManager只是用于管理Window内部的视图,通过方法setWindowManager,可以看到Window中是如何创建WindowManager的,具体源码如下:

public void setWindowManager(WindowManager wm, IBinder appToken, String appName,            boolean hardwareAccelerated) {        mAppToken = appToken;        mAppName = appName;        mHardwareAccelerated = hardwareAccelerated                || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);        if (wm == null) {            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);        }        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);  }

  通过该方法我们可以看到通过WindowManagerImpl的createLoaclWindowManager方法创建了一个WindowManager对象。

  从上图中,我们看出WindowManager接口是继承了ViewManager接口,从源码中可以看出ViewManager接口只有三个方法,具体如下:

public interface ViewManager{    public void addView(View view, ViewGroup.LayoutParams params);    public void updateViewLayout(View view, ViewGroup.LayoutParams params);    public void removeView(View view);}

  很好理解主要用于window中view的添加、更新和删除。

  WindowManager接口内容也比较简单,除了继承自ViewManager中的方法外,还定义了3个内部类和两个方法,具体API如下。

  在这里我们要重点关注一下LayoutParams这个内部类,此类定义了许多与窗口相关的属性,比如位置、窗口类型(主要有三类:Application Windows、Sub-windows、System windows)、行为选项标志、窗口透明度等等,在此不再贴源码了,有兴趣的可以自行查看。

  从window中的方法setWindowManager中可以看出创建的WindowManager的对象实际上是WindowManagerImpl,此类是WindowManager的实现类,源码如下:

public final class WindowManagerImpl implements WindowManager {    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();    private final Display mDisplay;    private final Window mParentWindow;    public WindowManagerImpl(Display display) {        this(display, null);    }    private WindowManagerImpl(Display display, Window parentWindow) {        mDisplay = display;        mParentWindow = parentWindow;    }    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {        return new WindowManagerImpl(mDisplay, parentWindow);    }    public WindowManagerImpl createPresentationWindowManager(Display display) {        return new WindowManagerImpl(display, mParentWindow);    }    @Override    public void addView(View view, ViewGroup.LayoutParams params) {        mGlobal.addView(view, params, mDisplay, mParentWindow);    }    @Override    public void updateViewLayout(View view, ViewGroup.LayoutParams params) {        mGlobal.updateViewLayout(view, params);    }    @Override    public void removeView(View view) {        mGlobal.removeView(view, false);    }    @Override    public void removeViewImmediate(View view) {        mGlobal.removeView(view, true);    }    @Override    public Display getDefaultDisplay() {        return mDisplay;    }}

  该实现类比较简单,主要持有Window类型的mParentWindow对象,并提供一系列的方法用于构建WindowManagerImpl对象,其他方法的实现主要调用WindowManagerGlobal对象中的响应方法。

  在window的setWindowManager方法主要调用了WindowManagerImpl的createLocalWindowManager创建了WindowManager对象,这样就将Window和WindowManager关联起来了,也就意味在调用WindowManager的addView、updateViewLayout、removeView时实际上操作的是Window内部的View,这一点可以通过查看WindowManagerGlobal相关方法的源码可以看出。

 

  疑问咨询或技术交流,请加入官方QQ群: (452379712)

 

作者:
出处:
 
本文版权归和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

转载于:https://www.cnblogs.com/jerehedu/p/4751208.html

你可能感兴趣的文章
第二阶段 铁大Facebook——十天冲刺(10)
查看>>
Java判断是否为垃圾_Java GC如何判断对象是否为垃圾
查看>>
多项式前k项和java_多项式朴素贝叶斯softmax改变
查看>>
java数组只能交换0下标和n_编程练习-只用0交换排序数组
查看>>
centos7安装mysql视频教程_centos7安装mysql(完整)
查看>>
php图片赋值,php如何优雅地赋值
查看>>
【探索HTML5第二弹01】HTML5的前世今生以及来世
查看>>
Failed to connect to remote VM. Connection refused. Connection refused: connect
查看>>
freeze
查看>>
JS时间转时间戳,时间戳转时间。时间显示模式。
查看>>
SAP HANA存储过程结果视图调用
查看>>
设计模式 ( 十八 ):State状态模式 -- 行为型
查看>>
OracleLinux安装说明
查看>>
nova分析(7)—— nova-scheduler
查看>>
Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)
查看>>
OpenMediaVault 搭建git,ssh无法连接问题
查看>>
java多线程之:Java中的ReentrantLock和synchronized两种锁定机制的对比 (转载)
查看>>
mysql性能优化学习笔记-参数介绍及优化建议
查看>>
【Web动画】SVG 实现复杂线条动画
查看>>
使用Wireshark捕捉USB通信数据
查看>>