[Android] 状态栏的一些认识
前段时间遇到几个关于状态栏的问题,又了解了一下状态栏相关的知识,现在做一下记录。
本文地址: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] 状态栏的一些认识的更多相关文章
- Android状态栏颜色修改
android状态栏颜色修改 状态栏颜色的修改在4.4和5.x环境下分别有不同的方式,低于4.4以下是不能修改的. 5.x环境下 方式一,状态栏将显示为纯净的颜色,没有渐变效果 /** * 状 ...
- Android状态栏透明(沉浸式效果)
Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487880 ...
- Android状态栏着色
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 状态栏着色,也就是我们经常听到的沉浸式状态栏,关于沉浸式的称呼网上也有很多吐槽的,这里就不做过多讨论了,以下我们统称状态栏着色,这样 ...
- android状态栏和NavigationBar的动态控制显示
项目在开发阅读器,阅读器对阅读界面的要求就是在工具栏不显示的状态下,ActionBar和NavigationBar都是不显示的,当工具栏显示时它们都出来,这就需要动态控制它们的显示与隐藏. 第一阶段: ...
- Translucent Bar Android状态栏自定义颜色
Android4.4 一个很重要的改变就是透明系统栏..新的系统栏是渐变透明的, 可以最大限度的允许屏幕显示更多内容, 也可以让系统栏和 Action Bar 融为一体, 仅仅留下最低限度的背景保护以 ...
- Android状态栏微技巧,带你真正意义上的沉浸式
记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解. 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发 ...
- 获取Android状态栏高度的屡试不爽的方法
文本转载于:http://blog.csdn.net/yinkai1205/article/details/8638864 如下代码所示: [java] view plaincopy private ...
- Android——状态栏通知栏Notification
1.AndroidManifest.xml注意要同时注册Notification02Activity <!-- 状态通知栏 Notification --> <acti ...
- android 状态栏、标题栏、屏幕高度
1.获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个getWindowVisibleDisplayFram ...
随机推荐
- IdentityServer4 Hybrid 模式
原文参考:Switching to Hybrid Flow and adding API Access back 接上篇:IdentityServer-Protecting an API using ...
- mybatis随笔一之SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是构建sqlSessionFactory的入口类 从该类的方法可知,它是通过不同的入参来构造SqlSessionFactory,除了最后一个config ...
- 选择 Python3.6 还是 Python 3.7
转自:白月黑羽在线教程:http://www.python3.vip/doc/blog/python/home/ 选择 Python3.6 还是 Python 3.7 Python 3.7 已经发布了 ...
- jmeter接口自动化部署jenkins教程
首先,保证本地安装并部署了jenkins,jmeter,xslproc 我搭建的自动化测试框架是jmeter+jenkins+xslproc ---注意:原理是,jmeter自生成的报告jtl文件,通 ...
- springboot+zuul(一)------实现自定义过滤器、动态路由、动态负载。
参考:https://blog.csdn.net/u014091123/article/details/75433656 https://blog.csdn.net/u013815546/articl ...
- python 生成唯一识别码
import uuid identity = str(uuid.uuid4()).encode('ascii')
- java-jmx使用
先粘一段内容 .程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布. .程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是 ...
- Double与BigDecimal 精度问题
转自:http://superivan.iteye.com/blog/963628 [1] 精确的浮点运算: 在Java里面,有时候为了保证数值的准确性需要精确的数据,先提供一个例子就可以发现问题了: ...
- [转]Magento2命令行配置之性能测试生成数据
本文转自:https://blog.csdn.net/xz_src/article/details/72799539 性能测试数据概述 使用Magento性能工具包或其他工具进行性能测试,你必定产生大 ...
- 在ASP.NET MVC使用JavaScriptResult
本例中,我们尝试把javascript程序搬至控制器中去.更好地在控制器编写程序. 首先来看看原来的写法. 在SepController控制器,添加如下操作: public ActionResult ...