手写沉浸式工具 - StatusBar

311 阅读1分钟

D041A394-2103-42c4-A19F-35CAAE3E98A8.png

前言

已经使用过的沉浸式使用方案有 ImmersionBar 等

实现原理很简单,主要是做异形屏等适配,这里不对适配进行讨论,可看下方链接中有详细说明

原理

设置 Window 相关属性,将 UI 延伸到状态栏,设置背景色

实现


/**
 *  沉浸式工具类
 */
object StatusBarHelper {

    fun setUp(activity: Activity, statusColor: Int, darkMode: Boolean, isFullScreen : Boolean = false) {
        val window = activity.window
        val decorView = window.decorView
        // Window 的 Flag,不同于 View
        var windowVisibility = decorView.systemUiVisibility

        //在 Android 5 上设置,5以下不做处理
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            // 两个属性会冲突,需要 clear
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            // 设置状态栏颜色
            window.statusBarColor = statusColor
        }
        // Android 6 上设置
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            windowVisibility = if (darkMode) {
                // 白底黑字
                windowVisibility or  View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
            } else {
                // 黑底白字
                windowVisibility and  View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
            }
        }

        if (isFullScreen){
            // 全屏,并且使得时间,电量等可见
            windowVisibility = windowVisibility or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        }

        decorView.systemUiVisibility = windowVisibility
    }


}

状态栏和布局重叠

虽然手动添加了一个占位 View ,但还是出现了重叠,这里查找原因

原因: 设置全屏后,ContentView 的布局延伸到了原来的状态栏位置,所以需要特殊处理


    /**
     * 处理布局和状态栏重叠
     */
    fun with(view : View){
        val paddingTop = getStatusBarHeight(view.context) + view.paddingTop
        view.setPadding(0, paddingTop, 0, 0)
    }

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

给顶部的 View 设置一个刚好状态栏大小的内部边距就可以了

测试效果

    // 在 Activity.onCreate() 中调用  
  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_mian)
        StatusBarHelper.setUp(this,Color.WHITE,true,true)
        StatusBarHelper.with(findViewById(R.id.ll_container))
    }

相关链接