android 状态栏梳理

Posted 终端研发部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 状态栏梳理相关的知识,希望对你有一定的参考价值。

android 很久了,状态栏 StatusBar 也是时候彻底梳理下了,以前也是改过全屏,改过颜色,4.4 和 5.0 都有不同的处理,以前写完就完了,现在回想起来已经不记得细节了,所以今天来梳理一下吧

本文涉及对 StatusBar 进行一下操作:

  • 改全屏,StatusBar 不显示

  • 改全屏,StatusBar 显示

  • StatusBar 透明

  • StatusBar 改颜色

  • StatusBar 改字体颜色

全屏,StatusBar 不显示

这个我们在闪屏页用,有4种写法:

// 方法1 
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

// 方法2
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
    <style name="AppThemefullScreen" parent="AppTheme">
       <item name="android:windowFullscreen">true</item>
   
</style>

   <!-- 方法4 -->
   android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"

这个好理解,就不展开了,有区别的是 方法2, 方法2 会生成一个状态栏由显示到隐藏的动画,模拟器上跑的挺好,但是真机会卡顿,所以大家还是修改 window 的属性吧,window 最优先显示

android 状态栏梳理

状态栏透明

其实在实际操作中,使用状态栏透明的操作不多,而且都不是为了让状态栏去透明,而是奔着状态栏在透明时会失去位置这个特性来,比如让图片延伸至标题栏

这里我们可以选择 theme 或是代码的方式,但是 theme 简单不是

values/style.xml

<style name="ImageTranslucentTheme" parent="AppTheme">
   <!--在Android 4.4之前的版本上运行,直接跟随系统主题-->
</style>

values-v19/style.xml

<style name="ImageTranslucentTheme" parent="AppTheme">
   <item name="android:windowTranslucentStatus">true</item>
   <item name="android:windowTranslucentNavigation">true</item>
</style>

values-v21/style.xml

<style name="ImageTranslucentTheme" parent="AppTheme">
   <item name="android:windowTranslucentStatus">false</item>
   <item name="android:windowTranslucentNavigation">true</item>
   <!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
   <item name="android:statusBarColor">@android:color/transparent</item>
</style>
标准情况下样子是这样的:

android 状态栏梳理

android 状态栏梳理

android 状态栏梳理

从上面图可以看到,状态栏一旦透明了,就失去位置了,虽然还在,但是我们的内容 view 就占据状态栏的位置了

注意啊:

  • activity 要是没有背景色,那么状态栏就是白色活透明的、

  • 5.0 时状态栏颜色随着 activity 背景色走,这个我测过了,就不上图了

  • 4.4 时状态栏颜色随着 toolbar 背景色走

纠正状态栏不占位的问题

这个就要用到 android:fitsSystemWindows=”true” 这个属性了

fitsSystemWindows 见名知意,意思是表示系统还是要占据状态栏的位置了,这样我们的状态栏和 ui 才能没有冲突

注意 fitsSystemWindows 需要设置在 layout 的跟视图上

设置 android:fitsSystemWindows=”true” 后,我们来看看:

android 状态栏梳理

android 状态栏梳理

这次 uI 就不占据 状态烂 的位置了,image 图也 跟着下来了,所以大家根据实际需求走

注意啊在 theme 设置 fitsSystemWindows ,会使所有的 view 都生效,这点在 toast 时有问题

android 状态栏梳理

修改状态栏颜色

这点在 5.0 以后很简单,兼容性也好

<style name="AppThemeTranslucent" parent="AppTheme">
       <item name="android:windowTranslucentStatus">false</item>
       <item name="android:windowTranslucentNavigation">true</item>
       <item name="android:statusBarColor">@color/colorAccent</item>
   
</style>

使用系统的 statusBarColor 参数就可以了

5.0 之后我们不改,系统状态栏也会跟着 app 颜色色调走,大家看看 color 里面颜色对应的部分

android 状态栏梳理

但是在 4.4 就坑爹了,虽说 android 从 4.4 开始支持修改状态栏颜色,但是在4.4 上实现很麻烦,还有兼容性问题,不确定所有的手机都好使

思路如下:

  • 先给设置 状态栏 为透明

  • 再给 window -> DecorView -> ContentView 在第一个位置 添加一个 状态栏 高度的 view 进来,内容 layout FitsSystemWindows 设为 true

fun setStatusBarColor() {
       var window = getWindow()
       if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {

           window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
           var systemContent = findViewById(android.R.id.content) as ViewGroup

           var statusBarView = View(this)
           var lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(this))

           statusBarView.setBackgroundColor(getResources().getColor(R.color.colorAccent))

           systemContent.getChildAt(0).setFitsSystemWindows(true);
           systemContent.addView(statusBarView, 0, lp);
       }
   }

   fun getStatusBarHeight(context: Context): Int {
       var result: Int = 0
       var resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android")
       if (resourceId > 0) {
           result = context.getResources().getDimensionPixelSize(resourceId)
       }
       return result;
   }

android 状态栏梳理

修改状态栏文字颜色

这个是在 6.0 之后才提供的功能,说是可以修改颜色,其实也只是能把颜色改为暗颜色和亮颜色,说白了就是白色和黑色

除了官方 rom 外,魅族和 miui 和也可以改

1. 官方 rom 实现:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
}// 白底黑字
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR// 黑丝白字
View.SYSTEM_UI_FLAG_LAYOUT_STABLE)

不设置的时候是白色字,设置上面之后就是黑色的字,大家想啊,亮的状态栏那肯定得黑色文字才能看的清不是

经过测试,魅族手机官方 api 也惯用,大家在测试时,一定要和测试手机断开之后才写入程序才行,要不状态栏不会生效,只有让 app 重新启动修改状态栏的操作才能有效

2. 魅族 rom 实现:

魅族官方提供了代码,提供了一个类,大家下载下来,然后直接用就可以啦

3. 小米 rom 实现:

小米也是一样,不过小米提供的是一个 demo ,大家耐心点下下来看看

最后网上有一些对官方原生,魅族,小米代码的封装,我试了试不生效,大家还是自己去看官放的代码后自己测试有效后才自己封装一下吧

如何统一修改 FitsSystemWindows

我们上面说了 FitsSystemWindows 要设置在 layout 根本布局,其实 window -> DecorView -> ContentView 更是根布局,给他设置 FitsSystemWindows 也是一样,下面代理里的版本判断大家根据自己需求执行更改

Window window = getWindow();//默认API 最低19 if 
(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {      
    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);  
  ViewGroup contentView = window.getDecorView().findViewById(Window.ID_ANDROID_CONTENT);  
  contentView.getChildAt(0).setFitsSystemWindows(false);
}

扩展

  1. 使用CollapsingToolbarLayout使ToolBar具有折叠效果


效果的样子就是上面的,我记得好像不用设置一大堆代码就行,大家先按 layout 的思路走一遍,不行再上代码

具体的大家请看下面这篇:

1、Android修改状态栏颜色全方位教程

https://www.jianshu.com/p/932568ed31af

2、有人总结了些修改状态栏后的 bug

https://www.jianshu.com/p/48a4ce8e97c3

刘海屏适配

国内的刘海屏时刻在太坑了,国内厂商早在 google 之前就用上了 刘海屏 ,所以 google 在 android p 28 上提供的方法就别想用了啦,没戏,我们之只能挨个商家去适配…

这方面有非常好的文章,我就不复制了,大家直接看下面的资料把

google P 适配思路:

刘海屏适配全攻略
https://www.jianshu.com/p/561f7241153b

华为,小米,oppo,vivo 适配四思路

https://www.jianshu.com/p/f93683dcb8b6

阅读更多


相信自己,没有做不到的,只有想不到的

在这里获得的不仅仅是技术!

以上是关于android 状态栏梳理的主要内容,如果未能解决你的问题,请参考以下文章

状态栏在全屏对话框片段android中将其颜色更改为黑色

显示对话框片段时与状态栏重叠,仅在Android4.4中

Android 4.4 — 半透明状态/导航栏 — fitSystemWindows/clipToPadding 不能通过片段事务工作

Android状态栏颜色不变

Android:工具栏状态栏重叠

带有透明状态栏的全屏片段(以编程方式)