【Android 个人理解(三)】从源码剖析如何实现实现全屏效果

实现全屏的代码:

// 全屏显示
requestWindowFeature(Window.FEATURE_NO_TITLE);
//turning off the title at the top of the screen.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//the status bar will be hidden when an app window with this flag set is on the top layer. 

很明显,第一句是关闭标题栏,第二句是关闭状态栏。

但是,这个不够深入,我们从源码挨个分析。

一、requestWindowFeature()的源码:

/**
     * Enable extended window features.  This is a convenience for calling
     * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
     *
     * @param featureId The desired feature as defined in
     *                  {@link android.view.Window}.
     * @return Returns true if the requested feature is supported and now
     *         enabled.
     *
     * @see android.view.Window#requestFeature
     */
    public final boolean requestWindowFeature(int featureId) {
        return getWindow().requestFeature(featureId);
    }

由上我们知道,这个方法的作用直接等价于 getWindow().requestFeature(),是后者的方便调用的方式。其中的参数是Window类下的标记窗口特点的int标记,返回布尔值,如果为true时,说明参数传递的特点是支持的,被实现的。

由此我们来看Window类下定义的窗口特点的种类:

/**
 * Abstract base class for a top-level window look and behavior policy.  An
 * instance of this class should be used as the top-level view added to the
 * window manager. It provides standard UI policies such as a background, title
 * area, default key processing, etc.
 *
 * <p>The only existing implementation of this abstract class is
 * android.policy.PhoneWindow, which you should instantiate when needing a
 * Window.  Eventually that class will be refactored and a factory method
 * added for creating Window instances without knowing about a particular
 * implementation.
 */
public abstract class Window {
    /** 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;
    /**
     * Flag for enabling the Action Bar.
     * This is enabled by default for some devices. The Action Bar
     * replaces the title bar and provides an alternate location
     * for an on-screen menu button on some devices.
     */
    public static final int FEATURE_ACTION_BAR = 8;
    /**
     * Flag for requesting an Action Bar that overlays window content.
     * Normally an Action Bar will sit in the space above window content, but if this
     * feature is requested along with {@link #FEATURE_ACTION_BAR} it will be layered over
     * the window content itself. This is useful if you would like your app to have more control
     * over how the Action Bar is displayed, such as letting application content scroll beneath
     * an Action Bar with a transparent background or otherwise displaying a transparent/translucent
     * Action Bar over application content.
     */
    public static final int FEATURE_ACTION_BAR_OVERLAY = 9;
    /**
     * Flag for specifying the behavior of action modes when an Action Bar is not present.
     * If overlay is enabled, the action mode UI will be allowed to cover existing window content.
     */
    public static final int FEATURE_ACTION_MODE_OVERLAY = 10;
    /** 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;

    /** The default features enabled */
    @SuppressWarnings({"PointlessBitwiseExpression"})
    protected static final int DEFAULT_FEATURES = (1 << FEATURE_OPTIONS_PANEL) |
            (1 << FEATURE_CONTEXT_MENU);

    /**
     * The ID that the main layout in the XML layout file should have.
     */
    public static final int ID_ANDROID_CONTENT = com.android.internal.R.id.content;

以上是Window类所有的公开的成员变量。

先说明Window类的概括:顶级窗口的外观和行为的抽象基类,这个类的实例常常作为顶层视图添加到窗口管理器。它提供了标准UI方法,比如背景,标题区域等。

注意:唯一实现这个抽象类的类是android.policy.PhoneWindow,而且这个类也会被重写和通过工厂模式来创造新的实例。一般我们直接调用getWindow获得实例。

关于Window的实例,也属于View对象,只是这个对象在最底层,超越了我们应用的界限,我们可以通过工具看在内存中某个应用的视图树进一步理解。事实上,整个Android系统也可以看作由许多应用组成。这里不再对Window进行深究。

然后说明和全屏显示相关的标记:

/** Flag for the "no title" feature, turning off the title at the top
     *  of the screen. */
    public static final int FEATURE_NO_TITLE = 1;

(PS:本来想介绍大部分的的,实在有点多!)

然后是requestFeature(),从字面意思上就知道获得顶级窗口的外观的特点。当然requestWindowFeature()同前。

二、setFlags(int flags, int mask)的源码:

/**
     * Set the flags of the window, as per the
     * {@link WindowManager.LayoutParams WindowManager.LayoutParams}
     * flags.
     *
     * <p>Note that some flags must be set before the window decoration is
     * created (by the first call to
     * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)} or
     * {@link #getDecorView()}:
     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN} and
     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}.  These
     * will be set for you based on the {@link android.R.attr#windowIsFloating}
     * attribute.
     *
     * @param flags The new window flags (see WindowManager.LayoutParams).
     * @param mask Which of the window flag bits to modify.
     */
    public void setFlags(int flags, int mask) {
        final WindowManager.LayoutParams attrs = getAttributes();
        attrs.flags = (attrs.flags&~mask) | (flags&mask);
        mForcedWindowFlags |= mask;
        if (mCallback != null) {
            mCallback.onWindowAttributesChanged(attrs);
        }
    }

也是flag即标志,但为什么不是和上一句相同,因为换了对象了。前面是Window类的,后者是WindowManager.LayoutParams的。WindowManager好理解,就是窗口管理器,管Window对象的,那么LayoutParams:

LayoutParams are used by views to tell their parents how they want to be laid out.

就是说,这个被用来告诉他们的父对象如何排布他们。比如告诉linnerLayout View如何在自己上面放置gallery对象,这里告诉窗口管理器如何排布窗口是全屏还是可以溢出的等等。

注意:这个方法因为设置的是顶级窗口的属性,所以需要在一些其他设置布局的方法前面调用,比如setContentView()。

两个参数的意思:第一个是设置成什么样,第二个是设置哪里(byte型)。

而flags具体与哪些,有分别代表什么样的窗口布置特点。在WindowManager类下的LayoutParams里,这里拿出和FLAG_FULLSCREEN有关的的源码:

/** Window flag: allow window to extend outside of the screen. */
        public static final int FLAG_LAYOUT_NO_LIMITS   = 0x00000200;

        /** Window flag: Hide all screen decorations (e.g. status bar) while
         * this window is displayed.  This allows the window to use the entire
         * display space for itself -- the status bar will be hidden when
         * an app window with this flag set is on the top layer. */
        public static final int FLAG_FULLSCREEN      = 0x00000400;

        /** Window flag: Override {@link #FLAG_FULLSCREEN and force the
         *  screen decorations (such as status bar) to be shown. */
        public static final int FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800;
        

一目了然,再具体的可以看setFlag()方法和requestFeature()的具体实现,来做进一步了解。

谢谢~

时间: 2024-12-05 16:09:36

【Android 个人理解(三)】从源码剖析如何实现实现全屏效果的相关文章

Android的Handler,Looper源码剖析

之前了解android的消息处理机制,但是源码看的少,现在把Looper,Handler,Message这几个类的源码分析一哈 android的消息处理有三个核心类:Looper,Handler和Message.其实还有一个Message Queue(消息队列),但是MQ被封装到Looper里面了,我们不会直接与MQ打交道,因此我没将其作为核心类 Looper源码: Looper的字面意思是"循环者",它被设计用来使一个普通线程变成Looper线程.所谓Looper线程就是循环工作的线

HashMap(2) 源码剖析(推荐)

今天看代码,想到去年发生的HashMap发生的CPU使用率100%的事件,转载下当时看的三个比较不错的博客(非常推荐) 参考:http://coolshell.cn/articles/9606.html   http://github.thinkingbar.com/hashmap-analysis/ http://developer.51cto.com/art/201102/246431.htm 在 Java 集合类中,使用最多的容器类恐怕就是 HashMap 和 ArrayList 了,所以

JS魔法堂:mmDeferred源码剖析

一.前言 avalon.js的影响力愈发强劲,而作为子模块之一的mmDeferred必然成为异步调用模式学习之旅的又一站呢!本文将记录我对mmDeferred的认识,若有纰漏请各位指正,谢谢.项目请见:[email protected] 二.API说明 {Deferred} Deferred({Function|Object} mixin?) ,创建一个Deferred实例,当mixin的类型为Object时,将mixin的属性和函数附加到Deferred实例的Promise实例上. {Stri

Android消息处理机制:源码剖析Handler、Looper,并实现图片异步加载

引言 我们在做 Android 开发时,常常需要实现异步加载图片/网页/其他.事实上,要实现异步加载,就需要实现线程间通信,而在 Android 中结合使用 Handler.Looper.Message 能够让不同的线程通信,完成异步任务.虽然 Android 官方为我们提供了 AsyncTask 类来完成异步任务,但这个类存在许多问题,并不好用,而且,AsyncTask 也是通过 Handler 和 Thread 来实现异步加载的,所以学习这方面的知识是有必要的 本文讲解思路大致如下:绘制 A

Android多线程研究(1)——线程基础及源码剖析

从今天起我们来看一下Android中的多线程的知识,Android入门容易,但是要完成一个完善的产品却不容易,让我们从线程开始一步步深入Android内部. 一.线程基础回顾 package com.maso.test; public class TraditionalThread { public static void main(String[] args) { /* * 线程的第一种创建方式 */ Thread thread1 = new Thread(){ @Override publi

boost.asio源码剖析(三) ---- 流程分析

* 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: 1 #include <iostream> 2 #include <boost/asio.hpp> 3 4 // 异步连接回调函数 5 void on_connect(boost::system::error_code ec) 6 { 7 if (ec) // 连接失败, 输出错误码 8 std::cout << "async connect error:"

Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机

Android源码浅析(三)--Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没仔细的梳理源码的入门逻辑,今天也就来讲一个源码的玩法,各位看官,一起学习学习! 看本篇博客之前,先看下我的前面两篇 Android源码浅析(一)--VMware Workstation Pro和Ubuntu Kylin 16.04 LTS安装配置 Android源码浅析(二)--Ubuntu Roo

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t[转]

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t Author:Echo Chen(陈斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:October 23h, 2014 1.ngx_list优势和特点 ngx_list _t是一个顺序容器,它实际上是动态数组和单向链表的结合体,扩容起来比动态数组简单的多,可以一次扩容一个数组,所以说它结合了 链表插入删除不需要移动的 和 数组下标快速索引 的优势

Django Rest Framework源码剖析(三)-----频率控制

一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过代理限制访问频率等,但是django rest framework自身就提供了访问频率的控制,可以从代码本身做控制. 二.频率控制内部原理概述 django rest framework 中频率控制基本原理基于访问次数和时间,通过计算实现,当然我们也可以自己定义频率控制方法.基本原理如下: 启用频率