Android 沉浸式状态栏 学习记录

198 阅读2分钟

记录完后,发现 -- 其实 官网 已经有指导了: developer.android.com/training/sy… developer.android.com/develop/ui/…

1、设置状态栏透明 - 在BaseActivity 中设置状态栏透明

/**  
* 设置状态栏透明 沉浸式  
*/  
open fun setTranslucentStatus() {  
    /*  

    //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色  
    val window = window  
    val decorView = window.decorView  
    //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间  
    decorView.systemUiVisibility =  
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN  
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)  
    decorView.systemUiVisibility =  
    decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR  
    window.statusBarColor = Color.TRANSPARENT  

    */  

    //https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md
    BarUtils.transparentStatusBar(this)  
}

2、设置paddingTop 或者marginTop - 在自定义的TitleView 中设置paddingTop 或者marginTop

override fun onAttachedToWindow() {  
super.onAttachedToWindow()  
    setStatusHeightToRoot()  
}

/**  
* 再 onAttachedToWindow 调用  paddingTop
*/  
private fun setStatusHeightToRoot() {  
    var paddingTop = SizeUtils.dp2px(30f)  
    try {  
        val windowInsets = ViewCompat.getRootWindowInsets(binding.root)  
        windowInsets?.let {  
        val top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top  
        val bottom = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).bottom  
        paddingTop = abs(bottom - top)  
        //LogUtils.e("setStatusHeightToRoot windowInsets paddingTop $paddingTop")  
        } ?: run {  
        paddingTop = BarUtils.getStatusBarHeight()  
        //LogUtils.e("setStatusHeightToRoot BarUtils.getStatusBarHeight paddingTop $paddingTop")  
        }  
    }catch (_:Exception){  

    }  
    binding.root.setPadding(0,paddingTop,0,0)  
}
/**  
* 再 onAttachedToWindow 调用  marginTop
*/  
private fun setStatusHeightToRoot() {  
    var marginTop = SizeUtils.dp2px(30f)  
    try {  
        val windowInsets = ViewCompat.getRootWindowInsets(binding.root)  
        windowInsets?.let {  
        val top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top  
        val bottom = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).bottom  
        marginTop = abs(bottom - top)  
    } ?: run {  
        marginTop = BarUtils.getStatusBarHeight()  
    }  
    }catch (_:Exception){  

    }  
    binding.root.updateLayoutParams<MarginLayoutParams> {  
        topMargin = if(marginTop >= 0) SizeUtils.dp2px(30f) else marginTop  
        leftMargin = 0  
        bottomMargin = 0  
        rightMargin = 0  
    }  
}

image.png

3、参考工具类 - 栏相关 -> BarUtils.java

getStatusBarHeight                   : 获取状态栏高度(px)
setStatusBarVisibility               : 设置状态栏是否可见
isStatusBarVisible                   : 判断状态栏是否可见
setStatusBarLightMode                : 设置状态栏是否为浅色模式
isStatusBarLightMode                 : 判断状态栏是否为浅色模式
addMarginTopEqualStatusBarHeight     : 为 view 增加 MarginTop 为状态栏高度
subtractMarginTopEqualStatusBarHeight: 为 view 减少 MarginTop 为状态栏高度
setStatusBarColor                    : 设置状态栏颜色
setStatusBarColor4Drawer             : 为 DrawerLayout 设置状态栏颜色
transparentStatusBar                 : 透明状态栏
getActionBarHeight                   : 获取 ActionBar 高度
setNotificationBarVisibility         : 设置通知栏是否可见
getNavBarHeight                      : 获取导航栏高度
setNavBarVisibility                  : 设置导航栏是否可见
isNavBarVisible                      : 判断导航栏是否可见
setNavBarColor                       : 设置导航栏颜色
getNavBarColor                       : 获取导航栏颜色
isSupportNavBar                      : 判断是否支持导航栏
setNavBarLightMode                   : 设置导航栏是否为浅色模式
isNavBarLightMode                    : 判断导航栏是否为浅色模式
transparentNavBar                    : 透明导航栏

juejin.cn/post/720356…

juejin.cn/post/687819…

API 30新特性:WindowInsetsController

Android沉浸式状态栏,看完这篇就够了!

随手记Android沉浸式状态栏的踩坑之路

Android 系统 Bar 沉浸式完美兼容方案

操作Android窗口的几种方式?WindowInsets与其兼容库的使用与踩坑

Android Detail:Window 篇—— WindowInsets 与 fitsSystemWindow