Android 状态栏透明

新手学堂014

Android 状态栏透明,第1张

前言:最近项目大量用到状态栏透明,网上也出现很多库可以直接拿来用,个人认为没有必要那么重引用到一个库(有木有同学和我有一样的想法),所以研究了一番,在此做个记录加强记忆也便后期查阅,如果无意中有幸能帮助到你那就再好不过了。

Android 从 44 (SDK 19) 开始支持 系统栏(状态栏+导航栏)半透明 效果:

翻译一下就是:

TranslucentDecor 主题设置了两个属性 windowTranslucentStatus 和 windowTranslucentNavigation 都为 true,前者指定状态栏半透明、后者指定导航栏半透明。

本文只探讨“状态栏”

默认样式是这样:

可见 Toolbar 和系统状态栏之间有明显的分界,我们要实现的效果是 Toolbar 和状态栏背景统一,看起来像是一个整体(自行脑补)。

按照官方文档,我们自定义主题:

对应的 Activity 引用该主题:

我看来看看效果:

虽然实现了半透明,但是布局被状态栏覆盖,接下来在布局文件中设置 fitSystemWindows (注意加到根节点 ConstraintLayout 上):

来看看效果:

虽然布局没有被状态栏覆盖,但是状态栏背景显然这不是我们想要的效果😭

为什么状态栏会这么奇怪?

文章开头的定义中我们说了,布局文件会延伸到状态栏所占区域下, fitsSystemWindows 的作用是给对应的 View 增加 padding(这里以 ConstraintLayout 为例),目的是为了让其内容不被状态栏遮挡。

在我们的布局文件中 ConstraintLayout 没有设置背景(默认白色),所以状态栏默认的半透明背景色和 ConstraintLayout 的白色背景叠加,就变成了上图中的效果。

总结两个基本概念:

1、 windowTranslucentStatus 设置为true之后,状态栏默认是 半透明 的(44 是黑色到透明色渐变,50+ 是纯黑色半透明),和我们要求的 透明 相去甚远。更重要的是,布局会延伸到状态栏底下。

2、 android:fitsSystemWindows 简单理解 就是 View 为了适配系统状态栏和导航栏(不被遮挡)自动 增加 padding ,当然真正的实现原理比这复杂很多而且不同的 View 可以自定义实现方式。

所以,为了实现文章开头提出来的“状态栏透明”效果,我们需要处理:

设置 windowTranslucentStatus 为 true,让状态栏半透明。

在根节点设置 android:fitsSystemWindows 使其不被状态栏遮挡。

Android 44 暂时没有办法去掉状态栏的渐变。

Android 50+ 开始支持修改状态栏颜色,设置透明色即可把半透明去掉。

看看效果:

我们看到即使状态栏透明了,但是其底色是一片白,因为跟节点 ConstraintLayout 没有设置背景,大多情况下我们不会给整个跟节点设置颜色,可以考虑把 android:fitsSystemWindows 设置到子 View 上,本例中是 AppBarLayout (50+ 无效,只能显式给 AppBarLayout 加 padding,可以利用其背景色),实际项目中可灵活调整。

最终效果:

至此,完成状态栏透明效果,网上有很多库,实际上都是基于此原理,在此基础上再自定义 View 做为状态栏背景。

https://developerandroidcom/about/versions/android-44html

实现功能 

1步骤: 

1) 创建一个工程,主布局就先做一个ImageView,自己找个好看的做src。 

2) 在Activity重写的onCreate方法中获得窗口视图对象(DecorView) 

3) 设置DecorView的SystemUiVisibility 

4) 设置导航条、状态栏的颜色–>透明 

5) 获取当前Activity的ActionBar并隐藏

2具体代码和注释: 

获取DecorView对象

@Override

protected void onCreate(Bundle savedInstanceState) {

    

    View decorView = getWindow()getDecorView();

    

}

设置SystemUiVisibility

int option = ViewSYSTEM_UI_FLAG_FULLSCREEN // 全屏标记

    | ViewSYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // 布局全屏标记,避免退出全屏模式时内容被覆盖

    | ViewSYSTEM_UI_FLAG_HIDE_NAVIGATION // 隐藏导航栏标记

    | ViewSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION // 布局隐藏导航栏标记,同理

    | ViewSYSTEM_UI_FLAG_IMMERSIVE_STICKY // 粘性沉浸体验

    | ViewSYSTEM_UI_FLAG_LAYOUT_STABLE; // 确保上述标记稳定// 此方法用来设置系统UI的可见性,系统UI包括状态栏、ActionBar、导航栏devorViewsetSystemUiVisibility(option);

设置状态栏、导航栏的颜色:

getWindow()setStatusBarColor(ColorTRANSPARENT);// ColorTRANSPARENT = 0 表示#00000000即透明颜色

getWindow()setNavigationBarColor(ColorTRANSPARENT);

获取本页面的ActionBar并隐藏起来

ActionBar actionBar = getSupportActionBar(); // 注意:此处用的Activity继承的是

AppCompatActivity(它继承的是FragmentActivity)

// 所以调用的是getSupport方法,如果继承Activity则直接调用get方法

assert actionBar != null; // 这一句可以不理会,反正我是Ctrl + F1提示出来的,意思其实是判断如果actionBar不为空则向下执行。

actionBarhide();

注意:最后一点注意事项是:只支持Android API 21以上的手机

Android44以后, 可以将状态栏设置为透明, 或者任意颜色 

1 全屏模式 

 

2 着色模式 

在Android44之后提供了可以修改状态栏的属性接口后,我们可以直接通过style文件来配置状态栏, 但是需要注意的是, 为了兼容44以下的版本, 所以必须在配置多个API级别的values文件 这里直接借参考文章中的图: 

 

最基本的在44版本之下会加载默认的values/stylesxml, 如果在44版本会加载 values-v19/stylesxml, 50以上加载 values-v21/stylesxml文件 具体配置如下:

values/stylesxml

<style name="ImageTranslucentTheme" parent="AppTheme">

<!--在Android 44之前的版本上运行,直接跟随系统主题--></style>123

values-v19/stylesxml

<style name="ImageTranslucentTheme" parent="ThemeAppCompatLightDarkActionBar">

<item name="android:windowTranslucentStatus">true</item>

<item name="android:windowTranslucentNavigation">true</item>

</style>1234

values-v21/stylesxml

<style name="ImageTranslucentTheme" parent="ThemeAppCompatLightDarkActionBar">

<item name="android:windowTranslucentStatus">false</item>

<item name="android:windowTranslucentNavigation">true</item>

<!--Android 5x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->

<item name="android:statusBarColor">@android:color/transparent</item>

</style>