沉浸式状态栏实现及遇到的坑

Android4.4以前的版本,状态栏都是一块黑色的,个人认为还是比较丑的。自4.4开始,Android已经支持透明状态栏了(俗称沉浸式状态栏)。个人认为支持沉浸式状态栏的app逼格还是比较高的,为了紧跟潮流,我们项目中也准备加入沉浸式状态栏。在实现沉浸式状态栏的过程中踩了不少的坑,特此记录下来。

如何实现状态栏

Android 4.4以上实现方式

Android 4.4版本提供了FLAG_TRANSLUCENT_STATUS,在Activity中加入此flag,可以设置状态栏透明。代码如下:

仅仅设置FLAG_TRANSLUCENT_STATUS,你会发现界面上的ToolBar会跑到状态栏上面去,如下图: 

通常我们会使用fitsSystemWindows属性来解决此问题。

fitSystemWindows官方描述:

Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity. 

简单描述:

这个属性的作用是让view可以根据系统窗口(如status bar)来调整自己的布局,如果值为true,就会调整view的paingding属性来给system windows留出空间(即给view添加一个值为状态栏高度的top padding)。

我们试着给ToolBar设置一下fitsSystemWindows属性为true。布局代码如下:

4.4的效果图如下:

注:有些4.4的系统上面状态栏并不是全透明的,而是渐变的。

Android 5.0以上实现方式

你会发现,已经实现了沉浸式状态栏效果了。如果运行在5.0以上的机器上面,会发现大部分手机会出现状态栏是半透明的,效果图如下:

我们能不能让将5.0以上的手机也设置为和4.4一样的全透明的状态栏呢?答案是肯定的!Android自5.0起,又为我们提供了设置状态栏颜色的API,我们可以自己设置状态栏的颜色。

在代码中再加入如下代码:

再在运行看看效果,状态栏已经变成全透明了。6.0运行效果图和上面4.4一样,就不再附图了。

Android 6.0以上设置状态栏字体颜色

默认状态栏字体颜色是白色的,如果ToolBar的颜色较浅,那么状态栏上白色的字看不怎么清楚。

Android6.0以后,我们可以使用代码将状态栏字体的颜色设置为黑色了,代码如下:

设置了深色状态栏字体的效果图如下:

踩过的坑

如果你认为已经已经完美实现了,那真是too young to simple。下面是一些我踩过的坑。

与软键盘冲突的坑

如果在界面中有EditText的话,你会发现当软件盘弹出的时候(Activity已经设置了adjustResize),ToolBar的内容都被顶上去了,但是EditText输入框却被有顶上来(正常情况应该是ToolBar没事,输入框被软键盘顶上去),如下图:

这是为什么呢?经研究发现原来是fitsSystemWindows属性搞的鬼。哪个View设置了fitsSystemWindows=true,这个View就会被软件盘顶上去。所以说,fitsSystemWindows不能乱用,会有意想不到的坑。

那能不能不用fitsSystemWindows呢?既然上面说了,fitsSystemWindows=true的作用是给View添加值为状态栏高度的padding,那我们何不自己手动给ToolBar添加padding呢?

我们去掉ToolBar上的fitsSystemWindows属性,并设置一下ToolBar的padding,代码如下:

去掉ToolBar的fitsSystemWindows属性,并加上加上上面的代码,软键盘弹出时ToolBar正常了,但是输入框还是没有弹出来。

解决方式1 

刚才上面给ToolBar设置了fitsSystemWindows=true,结果ToolBar的内容被顶上去了,那我们能不能给输入框设置一个fitsSystemWindows=true属性呢?试一下就知道了!

试了之后你会发现,果然可以,但是输入框的高度变了,其实是输入框的padding增加了状态栏的高度。如果设计和产品能接受这种效果,那这也不失为一种解决方法。很显然,一般都不会接受这种效果的,就算设计和产品能接受,我们开发也不能接受!

那有没有更好的方法呢?到网上搜索发现下面一种解决方案。

解决方式2 

添加上面的类,然后在Activity的onCreate方法中的setContentView后面加上如下代码:

然后运行,输入框能够正常被顶上去,而且输入框的布局有没有受到影响。

该解决方案的原理是,给界面的根布局设置一个监听器,当界面大小有变化的时候,如键盘弹出的时候,重新设置一下根布局的高度,再调用requestLayout对界面进行重绘。

注:不知道这种解决方案会不会引起其他的问题,目前暂时没有发现,如果哪位知道有什么问题,请指点一下,谢谢!

华为EMUI3.1上的坑

将上面的沉浸式代码放在EMUI3.1系统的手机(如华为荣耀7)上面跑,你会发现,根本没有沉浸式效果,状态栏是透明的,显示的是桌面上的颜色,如下图:

经验证,原来是EMUI3.1系统的原因,很多App(如网易云音乐等)也是在EMUI3.0上有沉浸式的效果,到了EMUI3.1却没有效果了。在EMUI3.1没有沉浸式效果如果和4.4以前一样是黑的也就算了,这样透明的显示桌面颜色实在难看。

后来发现去掉下面这句代码,可以让其有沉浸式的效果。

效果如下:

不过它的状态栏不是全透明的,而是像某些4.4的系统一样是渐变的,不过总比原来的效果好。

这里我们加一个判断,判断如果不是EMUI3.1的系统,才调用clearFlags清除掉FLAG_TRANSLUCENT_STATUS。

具体代码如下:

ActionMode上的坑

ActionMode是一种Context Menu,它悬浮在ToolBar活着ActionBar上面。现在已经基本上很少app在用ActionMode了,所以可能很多人可能没有用过,没用过的可以看看这篇文章http://blog.csdn.net/xyz_lmn/article/details/12754785。

公司项目中使用到了ActionMode(历史遗留代码),在实现沉浸式的效果中,发现ActionMode并不支持沉浸式。ActionMode弹出来的时候,状态栏会变成黑色的,效果如下:

ActionMode弹出前:

ActionMode弹出后:

遇到这个问题的时候,第一想法就是能不能和ToolBar一样给ActionMode设置一个值为状态栏高度的padding,然后将它顶到状态栏里面去。

在Stackoverflow上面搜了一种方法可以将ActionMode顶到状态栏上面去,给Activity加一个Flag即可,代码如下:

看到能将ActionMode顶到状态栏中去时心里已经在开始偷着乐了,接下来只要给ActionMode设置一个padding即可。然而发现ActionMode根本没有提供在代码中设置高度和padding的API,只能在style中设置高度和padding。这样就有一个问题,因为Android手机碎片化严重,导致不同厂商的不同手机状态栏的高度不一致,所以使用这个方法会出现有的手机ActionMode弹出时比ToolBar高或者低,不过也还能接受。

如果仅仅这样也就算了,没想到又引起了另外一个问题。在使用上面的flag之后(flag不能乱加啊,血和泪的教训),虽然ActionMode顶到状态栏了,但是在某些(如华为)带虚拟按键的手机(虚拟按键对开发者来说也是一个大坑),虚拟按键会遮挡底部的布局。

只能放弃这种方案,尼玛,怎么这么多坑,让我哭会(泪崩)!

没办法,问题还是得去解决啊!继续寻找其它解决方案。。。

这时候想到了在Android5.0以上我们可以设置状态栏的颜色,那可不可以在ActionMode弹出来的时候,给状态栏设置一个与ToolBar颜色一致的颜色呢?尝试一下吧,在BaseActivity中重写startSupportActionMode方法,在里面给状态栏设置颜色,具体代码如下:

没想到,居然可以。不过只能兼容5.0以上的手机,4.4还是黑色。目前也只能这样了,后期项目中估计会将ActionMode干掉吧,到时候就OK了。如果大家又更好兼容ActionMode的方法请指点一下,谢谢!!!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容