前段时间遇到几个关于状态栏的问题,又了解了一下状态栏相关的知识,现在做一下记录。

本文地址:http://www.cnblogs.com/rossoneri/p/4316343.html

前戏和问题

首先一般的设备都含有两个bar:顶部的状态栏(statusbar)和底部的工具栏(NavigationBar),关于这两个Bar我最初的认识在于之前的文章:

[Android]获取系统顶部状态栏(StatusBar)与底部工具栏(NavigationBar)的高度

通过之前文章的方法就可以获取屏幕高度,来对界面进行一番设计。但后来我突然发现了一个棘手的新问题,我遇到了这么一个蛋疼的界面:

它竟然把两个Bar合并到一起了。。。我去。。

因为之前的一个控件设计是考虑了上下两条Bar的高度,然后相对顶部工具栏来进行计算,结果遇上这么个屏幕,界面的控件纵向显示就出现了小的偏移,大概30dp左右。

好了,问题来了,那就着手解决吧。

思考和解决

既然你把上下的Bar合并在一起,那么原来顶部的statusbar是隐藏了么?

我先用前文提到的方法试试输出顶部状态栏的高度,结果得到一个高度,是25。嗯,跟我看到的大概30dp高度差不多,也就是说顶部状态栏高度是存在的。那是被隐藏了么?

想知道这个,就需要找找Android是否有提供一个获取statusbar显示状态的方法。查了查API,找到了一个方法:

 int n = mActivity.getWindow().getDecorView().getSystemUiVisibility();

结果得到 n =  0

看了看 0 的含义:

    /**
* Special constant for {@link #setSystemUiVisibility(int)}: View has
* requested the system UI (status bar) to be visible (the default).
*
* @see #setSystemUiVisibility(int)
*/
public static final int SYSTEM_UI_FLAG_VISIBLE = 0;

也就是说顶部的statusbar是默认的可见状态。WTF,我明明看不见了,你竟然说还是默认的显示状态。好吧,难道这个statusbar移到底部合并 显示 了吗?但高度不对呀。

带着疑问,我又试着输出底部工具栏高度,得到了48。跟之前的设备一样,底部的高度没有变。

得,说到底,两条Bar的高度是都可以获取到的,而且值和正常的一样,虽然顶部的看不见,但状态还是默认的可见的,显示成这个样式是系统定制时设定的。姑且这么理解吧。

既然底部的工具栏高度没有变化,我的控件就重新以底部为参照来计算好了。用这个方法,暂且解决了控件显示位置的问题。

拓展知识

经过上面的问题,好歹是解决了眼前的bug。趁着看到这一块,我就又多了解了一下表示bar状态的几个标识:

 /**
* Special constant for {@link #setSystemUiVisibility(int)}: View has
* requested the system UI (status bar) to be visible (the default).
*
* @see #setSystemUiVisibility(int)
*/
public static final int SYSTEM_UI_FLAG_VISIBLE = 0; /**
* Flag for {@link #setSystemUiVisibility(int)}: View has requested the
* system UI to enter an unobtrusive "low profile" mode.
*
* <p>This is for use in games, book readers, video players, or any other
* "immersive" application where the usual system chrome is deemed too distracting.
*
* <p>In low profile mode, the status bar and/or navigation icons may dim.
*
* @see #setSystemUiVisibility(int)
*/
public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001; /**
* Flag for {@link #setSystemUiVisibility(int)}: View has requested that the
* system navigation be temporarily hidden.
*
* <p>This is an even less obtrusive state than that called for by
* {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls
* (Home, Back, and the like) on screen, <code>SYSTEM_UI_FLAG_HIDE_NAVIGATION</code> will cause
* those to disappear. This is useful (in conjunction with the
* {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and
* {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN}
* window flags) for displaying content using every last pixel on the display.
*
* <p>There is a limitation: because navigation controls are so important, the least user
* interaction will cause them to reappear immediately. When this happens, both
* this flag and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically,
* so that both elements reappear at the same time.
*
* @see #setSystemUiVisibility(int)
*/
public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002; /**
* Flag for {@link #setSystemUiVisibility(int)}: View has requested to go
* into the normal fullscreen mode so that its content can take over the screen
* while still allowing the user to interact with the application.
*
* <p>This has the same visual effect as
* {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN
* WindowManager.LayoutParams.FLAG_FULLSCREEN},
* meaning that non-critical screen decorations (such as the status bar) will be
* hidden while the user is in the View's window, focusing the experience on
* that content. Unlike the window flag, if you are using ActionBar in
* overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
* Window.FEATURE_ACTION_BAR_OVERLAY}, then enabling this flag will also
* hide the action bar.
*
* <p>This approach to going fullscreen is best used over the window flag when
* it is a transient state -- that is, the application does this at certain
* points in its user interaction where it wants to allow the user to focus
* on content, but not as a continuous state. For situations where the application
* would like to simply stay full screen the entire time (such as a game that
* wants to take over the screen), the
* {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN window flag}
* is usually a better approach. The state set here will be removed by the system
* in various situations (such as the user moving to another application) like
* the other system UI states.
*
* <p>When using this flag, the application should provide some easy facility
* for the user to go out of it. A common example would be in an e-book
* reader, where tapping on the screen brings back whatever screen and UI
* decorations that had been hidden while the user was immersed in reading
* the book.
*
* @see #setSystemUiVisibility(int)
*/
public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004; /**
* Flag for {@link #setSystemUiVisibility(int)}: When using other layout
* flags, we would like a stable view of the content insets given to
* {@link #fitSystemWindows(Rect)}. This means that the insets seen there
* will always represent the worst case that the application can expect
* as a continuous state. In the stock Android UI this is the space for
* the system bar, nav bar, and status bar, but not more transient elements
* such as an input method.
*
* The stable layout your UI sees is based on the system UI modes you can
* switch to. That is, if you specify {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
* then you will get a stable layout for changes of the
* {@link #SYSTEM_UI_FLAG_FULLSCREEN} mode; if you specify
* {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and
* {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}, then you can transition
* to {@link #SYSTEM_UI_FLAG_FULLSCREEN} and {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}
* with a stable layout. (Note that you should avoid using
* {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} by itself.)
*
* If you have set the window flag {@link WindowManager.LayoutParams#FLAG_FULLSCREEN}
* to hide the status bar (instead of using {@link #SYSTEM_UI_FLAG_FULLSCREEN}),
* then a hidden status bar will be considered a "stable" state for purposes
* here. This allows your UI to continually hide the status bar, while still
* using the system UI flags to hide the action bar while still retaining
* a stable layout. Note that changing the window fullscreen flag will never
* provide a stable layout for a clean transition.
*
* <p>If you are using ActionBar in
* overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
* Window.FEATURE_ACTION_BAR_OVERLAY}, this flag will also impact the
* insets it adds to those given to the application.
*/
public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100; /**
* Flag for {@link #setSystemUiVisibility(int)}: View would like its window
* to be layed out as if it has requested
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, even if it currently hasn't. This
* allows it to avoid artifacts when switching in and out of that mode, at
* the expense that some of its user interface may be covered by screen
* decorations when they are shown. You can perform layout of your inner
* UI elements to account for the navigation system UI through the
* {@link #fitSystemWindows(Rect)} method.
*/
public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200; /**
* Flag for {@link #setSystemUiVisibility(int)}: View would like its window
* to be layed out as if it has requested
* {@link #SYSTEM_UI_FLAG_FULLSCREEN}, even if it currently hasn't. This
* allows it to avoid artifacts when switching in and out of that mode, at
* the expense that some of its user interface may be covered by screen
* decorations when they are shown. You can perform layout of your inner
* UI elements to account for non-fullscreen system UI through the
* {@link #fitSystemWindows(Rect)} method.
*/
public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400; /**
* Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
* hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. If this flag is
* not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
* user interaction.
* <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
* has an effect when used in combination with that flag.</p>
*/
public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800; /**
* Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
* hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
* bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. Use this flag to create an immersive
* experience while also hiding the system bars. If this flag is not set,
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
* interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
* if the user swipes from the top of the screen.
* <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
* system gestures, such as swiping from the top of the screen. These transient system bars
* will overlay app’s content, may have some degree of transparency, and will automatically
* hide after a short timeout.
* </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
* with one or both of those flags.</p>
*/
public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000; /**
* @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
*/
public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE; /**
* @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead.
*/
public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to make the status bar not expandable. Unless you also
* set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
*/
public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide notification icons and scrolling ticker text.
*/
public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to disable incoming notification alerts. This will not block
* icons, but it will block sound, vibrating and other visual or aural notifications.
*/
public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide only the scrolling ticker. Note that
* {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies
* {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.
*/
public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide the center system info area.
*/
public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide only the home button. Don't use this
* unless you're a special part of the system UI (i.e., setup wizard, keyguard).
*/
public static final int STATUS_BAR_DISABLE_HOME = 0x00200000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide only the back button. Don't use this
* unless you're a special part of the system UI (i.e., setup wizard, keyguard).
*/
public static final int STATUS_BAR_DISABLE_BACK = 0x00400000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide only the clock. You might use this if your activity has
* its own clock making the status bar's clock redundant.
*/
public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to hide only the recent apps button. Don't use this
* unless you're a special part of the system UI (i.e., setup wizard, keyguard).
*/
public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to disable the global search gesture. Don't use this
* unless you're a special part of the system UI (i.e., setup wizard, keyguard).
*/
public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to specify that the status bar is displayed in transient mode.
*/
public static final int STATUS_BAR_TRANSIENT = 0x04000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to specify that the navigation bar is displayed in transient mode.
*/
public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to specify that the hidden status bar would like to be shown.
*/
public static final int STATUS_BAR_UNHIDE = 0x10000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to specify that the hidden navigation bar would like to be shown.
*/
public static final int NAVIGATION_BAR_UNHIDE = 0x20000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to specify that the status bar is displayed in translucent mode.
*/
public static final int STATUS_BAR_TRANSLUCENT = 0x40000000; /**
* @hide
*
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
* Flag to specify that the navigation bar is displayed in translucent mode.
*/
public static final int NAVIGATION_BAR_TRANSLUCENT = 0x80000000; /**
* @hide
*/
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;

标识位源码,5.0的SDK内容比原来的多了不少

关于几个常用的我挨个试验了一下

getWindow().getDecorView().setSystemUiVisibility(标识)

然后操作了一下程序,得到下面的初步结论:

SYSTEM_UI_FLAG_FULLSCREEN bar存在,内容消失 显示一个点
SYSTEM_UI_FLAG_HIDE_NAVIGATION navigation_bar消失
SYSTEM_UI_FLAG_FULLSCREEN status_bar消失
SYSTEM_UI_FLAG_LAYOUT_STABLE 不变
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 上下bar还在,但显示的内容拓展到被bar盖住的区域了好像
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 上下bar还在,显示的内容拓展到上面bar的位置
SYSTEM_UI_FLAG_IMMERSIVE 不变
SYSTEM_UI_FLAG_IMMERSIVE_STICKY 不变

可以结合着源码里的官方注释来看看

一个新问题

看完这,我突然想起来之前遇到的另一个问题:

我写了一个popupwindow,希望它在靠上的位置弹出来时这么显示

结果它是这么显示的:

哎我去,当时我真是百思不得其解,因为各种高度我都考虑到,写到计算代码里,意思是一旦遇到顶部显示的情况,popupwindow就自动向下偏移一个距离完整显示。

另外,popupwindow作为一个弹出时单独在最上层显示的控件,就算我不控制它,它也不应该显示一半吧。

后来我实在没办法就强行在代码里增加了35左右的高度好让它完整显示。

现在看来,原来是界面显示的时候,顶部边界并不是状态栏的bottom,而是整个屏幕的顶部。出现这个情况是因为statusbar盖住了上面的一部分而已,只是我不知道罢了。。

好了,下次设计界面的时候我会注意把statusbar的高度减掉的。。。

以上就是我对Android状态栏的一点新理解。若不正确,但求拍砖。

参考:

动态显示和隐藏状态栏

[Android] 状态栏的一些认识的更多相关文章

  1. Android状态栏颜色修改

    android状态栏颜色修改   状态栏颜色的修改在4.4和5.x环境下分别有不同的方式,低于4.4以下是不能修改的.   5.x环境下 方式一,状态栏将显示为纯净的颜色,没有渐变效果 /** * 状 ...

  2. Android状态栏透明(沉浸式效果)

    Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487880 ...

  3. Android状态栏着色

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 状态栏着色,也就是我们经常听到的沉浸式状态栏,关于沉浸式的称呼网上也有很多吐槽的,这里就不做过多讨论了,以下我们统称状态栏着色,这样 ...

  4. android状态栏和NavigationBar的动态控制显示

    项目在开发阅读器,阅读器对阅读界面的要求就是在工具栏不显示的状态下,ActionBar和NavigationBar都是不显示的,当工具栏显示时它们都出来,这就需要动态控制它们的显示与隐藏. 第一阶段: ...

  5. Translucent Bar Android状态栏自定义颜色

    Android4.4 一个很重要的改变就是透明系统栏..新的系统栏是渐变透明的, 可以最大限度的允许屏幕显示更多内容, 也可以让系统栏和 Action Bar 融为一体, 仅仅留下最低限度的背景保护以 ...

  6. Android状态栏微技巧,带你真正意义上的沉浸式

    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解. 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发 ...

  7. 获取Android状态栏高度的屡试不爽的方法

    文本转载于:http://blog.csdn.net/yinkai1205/article/details/8638864 如下代码所示: [java] view plaincopy private  ...

  8. Android——状态栏通知栏Notification

    1.AndroidManifest.xml注意要同时注册Notification02Activity <!-- 状态通知栏 Notification -->        <acti ...

  9. android 状态栏、标题栏、屏幕高度

    1.获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个getWindowVisibleDisplayFram ...

随机推荐

  1. MVC3学习:实现简单的相册管理和图片管理

    相册管理说白了就是文件夹管理,因此要用到命名空间using System.IO; 一.先来做相册管理,添加相册我就不做了,就是添加文件夹,这里主要做一下相册的显示.相册在页面上显示,需要一张图片,可以 ...

  2. Spring中内置的一些工具类

    学习Java的人,或者开发很多项目,都需要使用到Spring 这个框架,这个框架对于java程序员来说.学好spring 就不怕找不到工作.我们时常会写一些工具类,但是有些时候 我们不清楚,我们些的工 ...

  3. Spring学习--Spring事务相关速记

    数据库事务 事务特性: 原子性,事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做 一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态 隔离性, ...

  4. 详解C#泛型(三)

    一.前面两篇文章分别介绍了定义泛型类型.泛型委托.泛型接口以及声明泛型方法: 详解C#泛型(一) 详解C#泛型(二) 首先回顾下如何构建泛型类: public class MyClass<T&g ...

  5. google 被墙的解决办法

    昨晚无意中发现的东西,分享给各位使用,google搜索技术方面的东西还是很准确的,可惜被墙了,但是上有政策下有对策…… 谷歌地址: http://74.125.224.18/ http://91.21 ...

  6. mysql cmd 启动服务

    1.确定你的mysql 是否能正常工作登录数据库cmd--“命令提示字符”窗口录入,录入cd C:\mysql\bin 并按下回车键,将目录切换为 cd C:\mysql\bin再键入命令mysql ...

  7. Python模块: 命令行解析optionparser

    Python 有两个内建的模块用于处理命令行参数:一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数:另一个是 optparse,它功能强大,而 ...

  8. Java NIO 进程间通信

    转自:http://blog.csdn.net/lingzhm/article/details/45026119 传统的进程间通信的方式有大致如下几种: (1)   管道(PIPE) (2)   命名 ...

  9. 浅谈移动应用的跨平台开发工具(Xamarin和React Native)

    谈移动应用的跨平台开发不能不提HTML5,PhoneGap和Sencha等平台一直致力于使用HTML5技术来开发跨平台的移动应用,现在看来这个方向基本算是失败的,基于HTML5的移动应用在用户体验上与 ...

  10. PBN旁切转弯保护区组图

    旁切转弯是PBN(Performance Based Navigation基于性能导航)中使用频率最高的一种飞行方式,旁切转弯保护区支持最大120°的转弯. 旁切转弯保护区叠加图: 旁切转弯保护区分解 ...