在app开发中,通常都会修改状态栏样式,当你在搜索引擎上一顿操作后搜到的代码都是过时的。
当你把Android SDK 兼容版本调整到30,你会发现处理状态栏的部分代码开始划上横线(弃用)
问:新版API变成什么了?
答:
WindowInsetsControllerCompat
问:为啥要改?
答:当你打开WindowInsetsControllerCompat的构造方法你就会发现该api处理了不同版本的适配,不同于以前直接操作Window添加各种Flag来处理,处理状态栏等都提供了方法方便调用
public WindowInsetsControllerCompat(@NonNull Window window, @NonNull View view) {
if (SDK_INT >= 30) {
mImpl = new Impl30(window, this);
} else if (SDK_INT >= 26) {
mImpl = new Impl26(window, view);
} else if (SDK_INT >= 23) {
mImpl = new Impl23(window, view);
} else if (SDK_INT >= 20) {
mImpl = new Impl20(window, view);
} else {
mImpl = new Impl();
}
}
本次分享的代码分为以下功能:
1:状态栏显示控制
2:状态栏颜色控制
3:状态栏字体颜色控制
4:沉浸式状态栏设置
废话少说直接上代码
// 首先导入ktx核心包
implementation 'androidx.core:core-ktx:1.6.0'
1:状态栏显示控制
/**
* 显示状态栏
* @param isVisible 是否显示
*/
fun setStatusBarVisible(activity: Activity, isVisible: Boolean) {
val window = activity.window
WindowCompat.setDecorFitsSystemWindows(window, isVisible)
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
if (isVisible) {
controller.show(WindowInsetsCompat.Type.statusBars())
} else {
controller.hide(WindowInsetsCompat.Type.statusBars())
}
controller.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
<!-- 记得加上这个style 不然部分手机状态栏会变黑 -->
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
// 控制内容是否顶到状态栏上面(不清楚可以了解一下window和decorView的关系)
WindowCompat.setDecorFitsSystemWindows(window, isVisible)
// 显示可以控制的部分
WindowInsetsCompat.Type.statusBars() : 状态栏
WindowInsetsCompat.Type.navigationBars() : 底部导航栏
WindowInsetsCompat.Type.captionBar() :标题栏
WindowInsetsCompat.Type.systemBars() :前三者全部
// 控制状态栏操作效果
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
效果(状态栏):当全屏时,你下拉状态栏,状态栏出现后会在几秒后消失
使用效果:
StatusBarUtil.setStatusBarVisible(this, false)
---------------------------------------------------------------------------------------------------------------------------------
2:状态栏颜色控制
/**
* 设置状态栏颜色
* 这里还是直接操作window的statusBarColor
*/
fun setStatusBarColor(activity: Activity, @ColorInt color: Int) {
activity.window.statusBarColor = color
}
使用效果:
StatusBarUtil.setStatusBarColor(this,Color.BLUE)
---------------------------------------------------------------------------------------------------------------------------------
3:状态栏字体颜色控制
/**
* 设置状态栏字体颜色
* 此api只能控制字体颜色为 黑/白
* @param color 这里的颜色是指背景颜色
*/
fun setStatusBarTextColor(activity: Activity, @ColorInt color: Int) {
// 计算颜色亮度
val luminanceValue = ColorUtils.calculateLuminance(color)
WindowInsetsControllerCompat(activity.window, activity.window.decorView).let { controller ->
if (color == Color.TRANSPARENT) {
// 如果是透明颜色就默认设置成黑色
controller.isAppearanceLightStatusBars = true
} else {
// 通过亮度来决定字体颜色是黑还是白
controller.isAppearanceLightStatusBars = luminanceValue >= 0.5
}
}
}
使用效果:
//val backgroundColor=Color.WHITE
val backgroundColor=Color.BLUE
StatusBarUtil.setStatusBarColor(this,backgroundColor) //设置状态栏颜色
StatusBarUtil.setStatusBarTextColor(this,backgroundColor) // 字体颜色
---------------------------------------------------------------------------------------------------------------------------------
4:沉浸式状态栏设置
/**
* 沉浸式状态栏
* @param contentColor 内容颜色:获取内容的颜色,传入系统,它自动修改字体颜色(黑/白)
*/
fun immersiveStatusBar(activity: Activity,@ColorInt contentColor:Int) {
val window = activity.window.apply {
statusBarColor = Color.TRANSPARENT
}
// 设置状态栏字体颜色
setStatusBarTextColor(activity, contentColor)
// 把内容放到系统窗口里面 可以去了解一下Window和decorView的关系
WindowCompat.setDecorFitsSystemWindows(window, false)
}
使用效果:
val contentColor = Color.parseColor("#0000FF")
StatusBarUtil.immersiveStatusBar(this, contentColor)