5.0以上使用透明状态栏(设置系统通知栏颜色)

自己在使用手机的过程中都会看到其他app的透明状态栏(或者国内成为沉浸式状态栏),再看看自己app上放系统通知栏黑黑的一块,突兀又不和谐,就想着把自己的app也弄得比较炫一些。

言归正传,下面记录下操作步骤和可能有坑的点,欢迎指正~

1. 5.0系统以上
2. BaseActivity中加入
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//先将状态栏调整为透明
window.setStatusBarColor(Color.TRANSPARENT);

是不是看到那么多的FLAG_XXX心都累了,这些累人的FLAG_XXX我们先按下不表,我们直接来看下最后一行。
各位看官可能要说了,最后一行那么简单,不就是设置个状态栏颜色呗,整段代码可能就这行看得最清晰了。
嗯,单纯从代码的角度,这行是最清晰不过的了,但是前面的这些累人的FLAG_XXX可都跟这行的代码有着密切的关系。让我们直接进入这个方法中查看下

    /**
     * Sets the color of the status bar to {@code color}.
     *
     * For this to take effect,
     * the window must be drawing the system bar backgrounds with
     * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} and
     * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS} must not be set.
     *
     * If {@code color} is not opaque, consider setting
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
     * <p>
     * The transitionName for the view background will be "android:status:background".
     * </p>
     */
    public abstract void setStatusBarColor(@ColorInt int color);

仔细把注释看完,是不是就明白那些FLAG_XXX到底是为什么需要那样设置了。

简单来说,这个setStatusBarColor(@ColorInt int color)方法要求我们的window

  • 必须没有WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
    这是第二行代码window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);的由来
  • 必须有WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
    这则是第四行代码window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);的由来。

然后,当你需要的是非透明颜色的状态栏时,需要设置两个标志
分别是View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREENView.SYSTEM_UI_FLAG_LAYOUT_STABLE,这样就搞清楚了代码第三行所做的工作

window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
3. 根据app的主色调去调整状态栏的颜色(对于有actionBar之类的界面)

有眼尖的小伙伴们应该已经发现我们之前的代码上设置状态栏的颜色是透明,这没有达到我们需要的效果啊,我们需要的是跟app主色调相同的那个颜色,我当然也知道这点,可是为什么要先设置成透明的呢,这是因为考虑到有些界面我们会设置为全屏,不显示系统通知栏,这时就要区分这两种情况了。再根据自己的需求来设置颜色。
如果没有这方面的需求,直接在上一步设置需要的颜色就可以了。

4. fitsSystemWindows方法

其实到第三步做完,我们已经能看到通知栏变成了我们所想要的颜色,效果如下图

完成step3之后的效果

看起来已经搞定了啊,还需要做些什么呢。那是因为我们的ContentView中只有一个TextView,所以并不能很清楚地展示效果是如何,接下来,改造下ContentView再来观察下效果


把上图Textview改为RecyclerView

这次应该比较直观能看到问题所在了,我们的ContentView的区域被系统通知栏遮住了一块。
这需要我们在每个页面的根布局中加入以下这句话

android:fitsSystemWindows="true"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/layout"
              android:fitsSystemWindows="true" 
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@color/white"
              android:orientation="vertical">

不过每个页面加这个很麻烦,也可以全局的style中加入

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:fitsSystemWindows">true</item>
</style>

这时再来看下效果


加入fitsSystemWindows

已经没有遮挡了,这时才算真的大功告成。

5. 坑

效果达成了,难免会遇到一些坑,下面我记录下我遇到的几个问题点
- 有些界面需要全屏展示
上文说到的第三步,其实在实际运用中我是去判断是否有自定义的ActionBar存在,有则使用app主色调,没有则是第一步中的Transparent,所以在没有自定义ActionBar的界面会变成灰色的状态栏,解决方案是在这些特殊的界面全屏,我的做法是使用theme来达到全屏的效果

android:theme="@android:style/Theme.Light.NoTitleBar"

- Toast显示不正常问题
这个应该是Toast也被fitsSystemWindows限制的问题,解决方法是我们showToast的时候传入的是个系统上下文

context ------------> context.getApplicationContext()

- 自定义View显示不正常问题
如一部分view缺失等问题,这时需要把自定义view在代码或者xml中设置android:fitsSystemWindows="false"

setFitsSystemWindows(false);

或者

//第7行
<me.roadley.ui.VerticalTextView
                android:id="@+id/some_tv"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@color/some_color"
                android:fitsSystemWindows="false"
                app:text="@string/some_string"
                app:textColor="@color/white"
                app:textSize="14sp"
                android:layout_centerVertical="true"/>
后记

5.0开始,Google推出Material Design,使用Theme.Material(MD主题)或Theme.AppCompat主题并至少设置ColorPrimaryDark属性就可以实现status bar半透明效果。
不过我们的项目并没有使用AppCompat主题,而且个人觉得与自己的ActionBar相同的颜色这种感觉会比较好哈~

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

推荐阅读更多精彩内容

  • 前言 原文:http://blog.csdn.net/mybeta/article/details/5076032...
    naturs阅读 23,078评论 8 70
  • 在日常开发中,我们经常会遇到viewpager配合fragment的情况;这些fragment有的要求顶进状态栏,...
    我想做个程序猿阅读 6,158评论 0 1
  • Android沉浸式状态栏 Android状态栏默认是固定的黑底白字,这肯定是不被伟大的设计师所喜爱的,更有甚者,...
    filimoo阅读 1,357评论 0 8
  • 前言 首先请大家看几张图: 以上的效果,一般我们统称为沉浸式状态栏。其实,这种叫法不是很准确,而且也没有沉浸式状态...
    宇是我阅读 3,788评论 2 28
  • 何谓沉浸式状态栏## 说白了,沉浸式状态栏本质上就是给系统状态栏着色。当这个颜色和我们Activity中的Tool...
    chandarlee阅读 15,601评论 2 54