一、前言:
特点:
- 透明状态栏
- 状态栏背景颜色
- 状态栏文字颜色(亮|暗色模式)
- 支持Activity/Fragment/DrawerLayout
- Kotlin特性
- 一行代码实现
- 文档详细, Demo简单
注意:StatusBar 只只支持Kotlin状态栏的适配。
二、使用
1、在项目根目录的 build.gradle 添加仓库
allprojects {
repositories {
// ...
maven { url 'https://jitpack.io' }
}
}
2、在 module 的 build.gradle 添加依赖
implementation 'com.github.liangjingkanji:StatusBar:2.0.0'
3、使用1:
open class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//直接调用,参数1是背景色,参数2是字体颜色(白色/黑色)
immersive(resources.getColor(R.color.color_FFEC5C46), false)
}
}
4、使用2:
要求图片的一部分作为状态栏的背景
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_immerse_image)
immersive()
}
图片.png
如果这里你使用的是ActionBar, 则应该给ActionBar设置透明背景
图片.pngoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_immerse_image)
immersive()
setActionBarTransparent() // 给ActionBar设置透明背景
}
5、状态栏字体颜色
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dark_status_bar)
immersive(Color.YELLOW, true)
}
图片.png
immersive这个函数还可以传入View进去, 就会自动使用View的背景色作为状态栏颜色.
class MainActivity : BaseMenuActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar.inflateMenu(R.menu.menu_main)
toolbar.setOnMenuItemClickListener { onOptionsItemSelected(it) }
immersive(toolbar)
// or dark status bar
// immersive(toolbar, true)
}
}
6、辅助函数
图片.png三、源码:
private const val COLOR_TRANSPARENT = 0
// <editor-fold desc="透明状态栏">
/**
* 半透明状态栏
* 会导致键盘遮挡输入框, 为根布局设置[View.setFitsSystemWindows]为true可以解决
*
* @param translucent 是否显示透明状态栏
* @param darkMode 是否显示暗色状态栏文字颜色
*/
fun Activity.translucent(
translucent: Boolean = true,
darkMode: Boolean? = null
) {
if (Build.VERSION.SDK_INT >= 19) {
if (translucent) {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}
if (darkMode != null) {
darkMode(darkMode)
}
}
/**
* 使用视图的背景色作为状态栏颜色
*/
fun Activity.immersive(view: View, darkMode: Boolean? = null) {
val background = view.background
if (background is ColorDrawable) {
immersive(background.color, darkMode)
}
}
/**
* 设置透明状态栏或者状态栏颜色, 会导致状态栏覆盖界面
*
* 如果不指定状态栏颜色则会应用透明状态栏(全屏属性), 会导致键盘遮挡输入框
*
* @param color 状态栏颜色, 不指定则为透明状态栏
* @param darkMode 是否显示暗色状态栏文字颜色
*/
@SuppressLint("ObsoleteSdkInt")
fun Activity.immersive(@ColorInt color: Int = COLOR_TRANSPARENT, darkMode: Boolean? = null) {
when {
Build.VERSION.SDK_INT >= 21 -> {
when (color) {
COLOR_TRANSPARENT -> {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
var systemUiVisibility = window.decorView.systemUiVisibility
systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.decorView.systemUiVisibility = systemUiVisibility
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = color
}
else -> {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
var systemUiVisibility = window.decorView.systemUiVisibility
systemUiVisibility =
systemUiVisibility and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
systemUiVisibility = systemUiVisibility and View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.decorView.systemUiVisibility = systemUiVisibility
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = color
}
}
}
Build.VERSION.SDK_INT >= 19 -> {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
if (color != COLOR_TRANSPARENT) {
setTranslucentView(window.decorView as ViewGroup, color)
}
}
}
if (darkMode != null) {
darkMode(darkMode)
}
}
/**
* 获取颜色资源值来设置状态栏
*/
fun Activity.immersiveRes(@ColorRes color: Int, darkMode: Boolean? = null) =
immersive(resources.getColor(color), darkMode)
// </editor-fold>
//<editor-fold desc="暗色模式">
/**
* 开关状态栏暗色模式, 并不会透明状态栏, 只是单纯的状态栏文字变暗色调.
*
* @param darkMode 状态栏文字是否为暗色
*/
fun Activity.darkMode(darkMode: Boolean = true) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
var systemUiVisibility = window.decorView.systemUiVisibility
systemUiVisibility = if (darkMode) {
systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}
window.decorView.systemUiVisibility = systemUiVisibility
}
}
//</editor-fold>
// <editor-fold desc="间距">
/**
* 增加View的上内边距, 增加高度为状态栏高度, 防止视图和状态栏重叠
* 如果是RelativeLayout设置padding值会导致centerInParent等属性无法正常显示
*
* @param remove true: paddingTop = 状态栏高度
* false: paddingTop = 0
*/
fun View.statusPadding(remove: Boolean = false) {
if (this is RelativeLayout) {
throw UnsupportedOperationException("Unsupported set statusPadding for RelativeLayout")
}
if (Build.VERSION.SDK_INT >= 19) {
val statusBarHeight = context.statusBarHeight
val lp = layoutParams
if (lp != null && lp.height > 0) {
lp.height += statusBarHeight //增高
}
if (remove) {
if (paddingTop < statusBarHeight) return
setPadding(
paddingLeft, paddingTop - statusBarHeight,
paddingRight, paddingBottom
)
} else {
if (paddingTop >= statusBarHeight) return
setPadding(
paddingLeft, paddingTop + statusBarHeight,
paddingRight, paddingBottom
)
}
}
}
/**
* 创建假的透明栏
*/
private fun Context.setTranslucentView(container: ViewGroup, color: Int) {
if (Build.VERSION.SDK_INT >= 19) {
var simulateStatusBar: View? = container.findViewById(android.R.id.custom)
if (simulateStatusBar == null && color != 0) {
simulateStatusBar = View(container.context)
simulateStatusBar.id = android.R.id.custom
val lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight)
container.addView(simulateStatusBar, lp)
}
simulateStatusBar?.setBackgroundColor(color)
}
}
//</editor-fold>
//<editor-fold desc="ActionBar">
/**
* 设置ActionBar的背景颜色
*/
fun AppCompatActivity.setActionBarBackground(@ColorInt color: Int) {
supportActionBar?.setBackgroundDrawable(ColorDrawable(color))
}
fun AppCompatActivity.setActionBarBackgroundRes(@ColorRes color: Int) {
supportActionBar?.setBackgroundDrawable(ColorDrawable(resources.getColor(color)))
}
/**
* 设置ActionBar的背景颜色为透明
*/
fun AppCompatActivity.setActionBarTransparent() {
supportActionBar?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
//</editor-fold>
// <editor-fold desc="辅助">
/**
* 显示或隐藏导航栏, 系统开启可以隐藏, 系统未开启不能开启
*
* @param enabled 是否显示导航栏
*/
fun Activity.setNavigationBar(enabled: Boolean = true) {
if (Build.VERSION.SDK_INT in 12..18) {
if (enabled) {
window.decorView.systemUiVisibility = View.VISIBLE
} else {
window.decorView.systemUiVisibility = View.GONE
}
} else if (Build.VERSION.SDK_INT >= 19) {
val systemUiVisibility = window.decorView.systemUiVisibility
if (enabled) {
window.decorView.systemUiVisibility =
systemUiVisibility and View.SYSTEM_UI_FLAG_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
} else {
window.decorView.systemUiVisibility = systemUiVisibility or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
}
}
}
/**
* 设置是否全屏
*
* @param enabled 是否全屏显示
*/
fun Activity.setFullscreen(enabled: Boolean = true) {
val systemUiVisibility = window.decorView.systemUiVisibility
window.decorView.systemUiVisibility = if (enabled) {
systemUiVisibility or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
} else {
systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE and View.SYSTEM_UI_FLAG_FULLSCREEN.inv()
}
}
/**
* 是否有导航栏
*/
val Activity?.isNavigationBar: Boolean
get() {
this ?: return false
val vp = window.decorView as? ViewGroup
if (vp != null) {
for (i in 0 until vp.childCount) {
vp.getChildAt(i).context.packageName
if (vp.getChildAt(i).id != -1 && "navigationBarBackground" ==
resources.getResourceEntryName(vp.getChildAt(i).id)
) return true
}
}
return false
}
/**
* 如果当前设备存在导航栏返回导航栏高度, 否则0
*/
val Context?.navigationBarHeight: Int
get() {
this ?: return 0
val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android")
var height = 0
if (resourceId > 0) {
height = resources.getDimensionPixelSize(resourceId)
}
return height
}
/**
* 状态栏高度
*/
val Context?.statusBarHeight: Int
get() {
this ?: return 0
var result = 24
val resId = resources.getIdentifier("status_bar_height", "dimen", "android")
result = if (resId > 0) {
resources.getDimensionPixelSize(resId)
} else {
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
result.toFloat(), Resources.getSystem().displayMetrics
).toInt()
}
return result
}
// </editor-fold>
网友评论