博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Android] 状态栏的一些认识
阅读量:4306 次
发布时间:2019-06-06

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

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

:http://www.cnblogs.com/rossoneri/p/4316343.html 

前戏和问题

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

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

 

它竟然把两个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状态的几个标识:

1 /**  2      * Special constant for {
@link #setSystemUiVisibility(int)}: View has 3 * requested the system UI (status bar) to be visible (the default). 4 * 5 * @see #setSystemUiVisibility(int) 6 */ 7 public static final int SYSTEM_UI_FLAG_VISIBLE = 0; 8 9 /** 10 * Flag for {
@link #setSystemUiVisibility(int)}: View has requested the 11 * system UI to enter an unobtrusive "low profile" mode. 12 * 13 *

This is for use in games, book readers, video players, or any other 14 * "immersive" application where the usual system chrome is deemed too distracting. 15 * 16 *

In low profile mode, the status bar and/or navigation icons may dim. 17 * 18 * @see #setSystemUiVisibility(int) 19 */ 20 public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001; 21 22 /** 23 * Flag for {

@link #setSystemUiVisibility(int)}: View has requested that the 24 * system navigation be temporarily hidden. 25 * 26 *

This is an even less obtrusive state than that called for by 27 * {

@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls 28 * (Home, Back, and the like) on screen, SYSTEM_UI_FLAG_HIDE_NAVIGATION will cause 29 * those to disappear. This is useful (in conjunction with the 30 * {
@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and 31 * {
@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN} 32 * window flags) for displaying content using every last pixel on the display. 33 * 34 *

There is a limitation: because navigation controls are so important, the least user 35 * interaction will cause them to reappear immediately. When this happens, both 36 * this flag and {

@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically, 37 * so that both elements reappear at the same time. 38 * 39 * @see #setSystemUiVisibility(int) 40 */ 41 public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002; 42 43 /** 44 * Flag for {
@link #setSystemUiVisibility(int)}: View has requested to go 45 * into the normal fullscreen mode so that its content can take over the screen 46 * while still allowing the user to interact with the application. 47 * 48 *

This has the same visual effect as 49 * {

@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN 50 * WindowManager.LayoutParams.FLAG_FULLSCREEN}, 51 * meaning that non-critical screen decorations (such as the status bar) will be 52 * hidden while the user is in the View's window, focusing the experience on 53 * that content. Unlike the window flag, if you are using ActionBar in 54 * overlay mode with {
@link Window#FEATURE_ACTION_BAR_OVERLAY 55 * Window.FEATURE_ACTION_BAR_OVERLAY}, then enabling this flag will also 56 * hide the action bar. 57 * 58 *

This approach to going fullscreen is best used over the window flag when 59 * it is a transient state -- that is, the application does this at certain 60 * points in its user interaction where it wants to allow the user to focus 61 * on content, but not as a continuous state. For situations where the application 62 * would like to simply stay full screen the entire time (such as a game that 63 * wants to take over the screen), the 64 * {

@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN window flag} 65 * is usually a better approach. The state set here will be removed by the system 66 * in various situations (such as the user moving to another application) like 67 * the other system UI states. 68 * 69 *

When using this flag, the application should provide some easy facility 70 * for the user to go out of it. A common example would be in an e-book 71 * reader, where tapping on the screen brings back whatever screen and UI 72 * decorations that had been hidden while the user was immersed in reading 73 * the book. 74 * 75 * @see #setSystemUiVisibility(int) 76 */ 77 public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004; 78 79 /** 80 * Flag for {

@link #setSystemUiVisibility(int)}: When using other layout 81 * flags, we would like a stable view of the content insets given to 82 * {
@link #fitSystemWindows(Rect)}. This means that the insets seen there 83 * will always represent the worst case that the application can expect 84 * as a continuous state. In the stock Android UI this is the space for 85 * the system bar, nav bar, and status bar, but not more transient elements 86 * such as an input method. 87 * 88 * The stable layout your UI sees is based on the system UI modes you can 89 * switch to. That is, if you specify {
@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} 90 * then you will get a stable layout for changes of the 91 * {
@link #SYSTEM_UI_FLAG_FULLSCREEN} mode; if you specify 92 * {
@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and 93 * {
@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}, then you can transition 94 * to {
@link #SYSTEM_UI_FLAG_FULLSCREEN} and {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} 95 * with a stable layout. (Note that you should avoid using 96 * {
@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} by itself.) 97 * 98 * If you have set the window flag {
@link WindowManager.LayoutParams#FLAG_FULLSCREEN} 99 * to hide the status bar (instead of using {
@link #SYSTEM_UI_FLAG_FULLSCREEN}),100 * then a hidden status bar will be considered a "stable" state for purposes101 * here. This allows your UI to continually hide the status bar, while still102 * using the system UI flags to hide the action bar while still retaining103 * a stable layout. Note that changing the window fullscreen flag will never104 * provide a stable layout for a clean transition.105 *106 *

If you are using ActionBar in107 * overlay mode with {

@link Window#FEATURE_ACTION_BAR_OVERLAY108 * Window.FEATURE_ACTION_BAR_OVERLAY}, this flag will also impact the109 * insets it adds to those given to the application.110 */111 public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100;112 113 /**114 * Flag for {
@link #setSystemUiVisibility(int)}: View would like its window115 * to be layed out as if it has requested116 * {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, even if it currently hasn't. This117 * allows it to avoid artifacts when switching in and out of that mode, at118 * the expense that some of its user interface may be covered by screen119 * decorations when they are shown. You can perform layout of your inner120 * UI elements to account for the navigation system UI through the121 * {
@link #fitSystemWindows(Rect)} method.122 */123 public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;124 125 /**126 * Flag for {
@link #setSystemUiVisibility(int)}: View would like its window127 * to be layed out as if it has requested128 * {
@link #SYSTEM_UI_FLAG_FULLSCREEN}, even if it currently hasn't. This129 * allows it to avoid artifacts when switching in and out of that mode, at130 * the expense that some of its user interface may be covered by screen131 * decorations when they are shown. You can perform layout of your inner132 * UI elements to account for non-fullscreen system UI through the133 * {
@link #fitSystemWindows(Rect)} method.134 */135 public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;136 137 /**138 * Flag for {
@link #setSystemUiVisibility(int)}: View would like to remain interactive when139 * hiding the navigation bar with {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. If this flag is140 * not set, {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any141 * user interaction.142 *

Since this flag is a modifier for {

@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only143 * has an effect when used in combination with that flag.

144 */145 public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;146 147 /**148 * Flag for {
@link #setSystemUiVisibility(int)}: View would like to remain interactive when149 * hiding the status bar with {
@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation150 * bar with {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. Use this flag to create an immersive151 * experience while also hiding the system bars. If this flag is not set,152 * {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user153 * interaction, and {
@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system154 * if the user swipes from the top of the screen.155 *

When system bars are hidden in immersive mode, they can be revealed temporarily with156 * system gestures, such as swiping from the top of the screen. These transient system bars157 * will overlay app’s content, may have some degree of transparency, and will automatically158 * hide after a short timeout.159 *

Since this flag is a modifier for {

@link #SYSTEM_UI_FLAG_FULLSCREEN} and160 * {
@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination161 * with one or both of those flags.

162 */163 public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;164 165 /**166 * @deprecated Use {
@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.167 */168 public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;169 170 /**171 * @deprecated Use {
@link #SYSTEM_UI_FLAG_VISIBLE} instead.172 */173 public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE;174 175 /**176 * @hide177 *178 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked179 * out of the public fields to keep the undefined bits out of the developer's way.180 *181 * Flag to make the status bar not expandable. Unless you also182 * set {
@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.183 */184 public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;185 186 /**187 * @hide188 *189 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked190 * out of the public fields to keep the undefined bits out of the developer's way.191 *192 * Flag to hide notification icons and scrolling ticker text.193 */194 public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000;195 196 /**197 * @hide198 *199 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked200 * out of the public fields to keep the undefined bits out of the developer's way.201 *202 * Flag to disable incoming notification alerts. This will not block203 * icons, but it will block sound, vibrating and other visual or aural notifications.204 */205 public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000;206 207 /**208 * @hide209 *210 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked211 * out of the public fields to keep the undefined bits out of the developer's way.212 *213 * Flag to hide only the scrolling ticker. Note that214 * {
@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies215 * {
@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.216 */217 public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000;218 219 /**220 * @hide221 *222 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked223 * out of the public fields to keep the undefined bits out of the developer's way.224 *225 * Flag to hide the center system info area.226 */227 public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000;228 229 /**230 * @hide231 *232 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked233 * out of the public fields to keep the undefined bits out of the developer's way.234 *235 * Flag to hide only the home button. Don't use this236 * unless you're a special part of the system UI (i.e., setup wizard, keyguard).237 */238 public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;239 240 /**241 * @hide242 *243 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked244 * out of the public fields to keep the undefined bits out of the developer's way.245 *246 * Flag to hide only the back button. Don't use this247 * unless you're a special part of the system UI (i.e., setup wizard, keyguard).248 */249 public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;250 251 /**252 * @hide253 *254 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked255 * out of the public fields to keep the undefined bits out of the developer's way.256 *257 * Flag to hide only the clock. You might use this if your activity has258 * its own clock making the status bar's clock redundant.259 */260 public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000;261 262 /**263 * @hide264 *265 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked266 * out of the public fields to keep the undefined bits out of the developer's way.267 *268 * Flag to hide only the recent apps button. Don't use this269 * unless you're a special part of the system UI (i.e., setup wizard, keyguard).270 */271 public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;272 273 /**274 * @hide275 *276 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked277 * out of the public fields to keep the undefined bits out of the developer's way.278 *279 * Flag to disable the global search gesture. Don't use this280 * unless you're a special part of the system UI (i.e., setup wizard, keyguard).281 */282 public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;283 284 /**285 * @hide286 *287 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked288 * out of the public fields to keep the undefined bits out of the developer's way.289 *290 * Flag to specify that the status bar is displayed in transient mode.291 */292 public static final int STATUS_BAR_TRANSIENT = 0x04000000;293 294 /**295 * @hide296 *297 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked298 * out of the public fields to keep the undefined bits out of the developer's way.299 *300 * Flag to specify that the navigation bar is displayed in transient mode.301 */302 public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;303 304 /**305 * @hide306 *307 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked308 * out of the public fields to keep the undefined bits out of the developer's way.309 *310 * Flag to specify that the hidden status bar would like to be shown.311 */312 public static final int STATUS_BAR_UNHIDE = 0x10000000;313 314 /**315 * @hide316 *317 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked318 * out of the public fields to keep the undefined bits out of the developer's way.319 *320 * Flag to specify that the hidden navigation bar would like to be shown.321 */322 public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;323 324 /**325 * @hide326 *327 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked328 * out of the public fields to keep the undefined bits out of the developer's way.329 *330 * Flag to specify that the status bar is displayed in translucent mode.331 */332 public static final int STATUS_BAR_TRANSLUCENT = 0x40000000;333 334 /**335 * @hide336 *337 * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked338 * out of the public fields to keep the undefined bits out of the developer's way.339 *340 * Flag to specify that the navigation bar is displayed in translucent mode.341 */342 public static final int NAVIGATION_BAR_TRANSLUCENT = 0x80000000;343 344 /**345 * @hide346 */347 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状态栏的一点新理解。若不正确,但求拍砖。

 

参考:

转载于:https://www.cnblogs.com/rossoneri/p/4316343.html

你可能感兴趣的文章
不同情况通知执行的顺序
查看>>
bean.xml配置数据源和读取配置文件配置数据源
查看>>
PHP正则表达式
查看>>
CSS 设计指南(第3版) 初读笔记
查看>>
markdown学习/mou
查看>>
CentOS 搭建 LAMP服务器
查看>>
今天我注册博客园了,我很开心!
查看>>
游戏开发-从零开始 002
查看>>
N个串的最大公共子串——(9018_1856)
查看>>
VC编程心得
查看>>
mysql那些事(6) WHERE条件 字符串的引号
查看>>
微信支付配置参数:支付授权目录、回调支付URL
查看>>
Redis(四):Spring + JedisCluster操作Redis(集群)
查看>>
百度正式发布PaddlePaddle深度强化学习框架PARL
查看>>
[转]Installing Memcached on Windows
查看>>
JMeter测试组件
查看>>
测试用例设计方法
查看>>
直接从chrome中复制的body到postman中希望能自动识别去除空格
查看>>
走过小公司的坑之入职一周
查看>>
[ZJOI2007]棋盘制作 悬线法dp 求限制下的最大子矩阵
查看>>