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

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

作者: roadley | 来源:发表于2017-09-02 11:26 被阅读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相同的颜色这种感觉会比较好哈~

相关文章

  • StatusBar背景色和字体颜色设置

    设置状态栏背景色 支持5.0以上,4.4只支持设置是否半透明 设置状态栏字体颜色 支持6.0以上 - 只能设置白色...

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

    自己在使用手机的过程中都会看到其他app的透明状态栏(或者国内成为沉浸式状态栏),再看看自己app上放系统通知栏黑...

  • Android 5.0透明状态栏设置

    声明 这篇文章是针对Android 5.0及以上版本的系统进行透明的状态栏设置,Android 5.0以下的系统暂...

  • 沉浸式状态栏

    使用方法 注意事项 设置状态栏透明 修改状态栏颜色,支持4.4以上版本 设置状态栏黑色字体图标注意此方法只适配4....

  • 沉浸式页面效果

    设置状态栏背景透明 设置状态栏字体颜色 设置DecorView全屏 针对Toolbar(系统或者自定义),留出顶部...

  • 沉浸式效果

    Android 5.0 设置状态栏全透明,将布局顶到status bar上 StatusBarUtil 状态栏工具...

  • 2018-11-20透明式状态栏

    通过设置 Theme 主题设置状态栏透明 因为 API21 之后(也就是 android 5.0 之后)的状态栏,...

  • MaterialDesign沉浸式设计

    一.5.0及以上实现沉浸式状态栏 方式1:通过设置主题达到,状态栏的颜色跟随你的主题里面的colorPrimary...

  • 11. 沉浸式状态栏

    只有在Android 5.0 以上,才支持设置状态栏的颜色。 Build.VERSION.SDK_INT: 硬件设...

  • 沉浸、透明及白底黑字状态栏技巧

    我们知道,Android5.0以上已经可以通过设置colorPrimaryDark来改变状态栏的颜色。但是,大多数...

网友评论

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

      本文链接:https://www.haomeiwen.com/subject/jpihjxtx.html