Android 沉浸式状态/导航栏的实现以及布局重叠的适配(Kotlin)

本文章分以下内容:

  1. 沉浸式状态栏的实现
  2. 沉浸式导航栏的实现
  3. 适配实现沉浸式状态栏后导致的布局偏移
  4. 其他常见问题

一、沉浸式状态栏的实现

该方法用于表示内容是否超出至状态栏和底部导航栏显示,false表明超出。(这也就我们实现沉浸式后需要做适配的原因)

WindowCompat.setDecorFitsSystemWindows(window, false)

注意:当使用setDecorFitsSystemWindows()时,注意不要使用View.setSystemUiVisibility(),因为在源码中,对于Android4.1-10的手机仍旧采用了setSystemUiVisibility方法实现沉浸式。

设置状态栏透明

window.statusBarColor = Color.TRANSPARENT

二、沉浸式导航栏的实现

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            //当背景透明时去掉灰色蒙层
            window.isNavigationBarContrastEnforced = false
        }

        //导航栏颜色透明
        window.navigationBarColor = Color.TRANSPARENT

三、处理状态栏UI与布局内容产生的重叠

实现沉浸式后我们会发现,布局内容与状态栏、底部导航栏叠加在一起了,为了避免应用UI与系统UI产生重叠,所以我们要对其进行偏移。

 首先通过这个方法,获取insets。参数填入window.decorView,当然也可以使用位于实现沉浸式的页面的view,

   ViewCompat.setOnApplyWindowInsetsListener(view) { view, insets:WindowInsetsCompat ->
        
        }

那么insets具体是什么呢?实际上insets是描述一组用于窗口内容的插入。说人话就是:我们可以从insets中获取包括状态栏,导航栏等系统UI的位置距离,然后用于调整我们的应用UI的位置。接下来我们就来看如何实现

   ViewCompat.setOnApplyWindowInsetsListener(view) { view, insets:WindowInsetsCompat ->
          
          val systemWindow=insets.getInsets(WindowInsetsCompat.Type.systemBars() or 
                                      WindowInsetsCompat.Type.displayCutout())
           
          //为需要偏移的view设置padding
          moveView.setPadding(0,systemWindow.top,0,0)

            insets
        }

通过inset.getInsets()获取对应的系统UI的信息, 我们也可以通过 “or” 同时获取多种系统栏的距离。例如我们可以同时获取系统的状态栏和刘海屏高度,如果刘海屏的高度更高则返回的是刘海屏的高度。

因为沉浸式所导致的底部布局与导航栏重叠问题也一样迎刃而解了。

view.setPadding(0,0,0,systemWindow.bottom)

WindowInsetsCompat.Type参数解释:

WindowInsetsCompat.Type.ime();//键盘
WindowInsetsCompat.Type.displayCutout();//刘海屏
WindowInsetsCompat.Type.statusBars();//状态栏
WindowInsetsCompat.Type.navigationBars();//导航栏
WindowInsetsCompat.Type.captionBar();//标题栏
WindowInsetsCompat.Type.systemBars();//状态栏,导航栏和标题栏
WindowInsetsCompat.Type.systemGestures();//系统手势 
WindowInsetsCompat.Type.mandatorySystemGestures();//强制性系统手势
WindowInsetsCompat.Type.tappableElement();//可点击区域

四、其他常见问题

状态栏字体颜色修改:

//状态栏字体改为白色
WindowCompat.getInsetsController(window,window.decorView).isAppearanceLightStatusBars = false

//状态栏字体改为黑色
WindowCompat.getInsetsController(window,window.decorView).isAppearanceLightStatusBars = true

导航栏按钮颜色修改: 

WindowCompat.getInsetsController(window,window.decorView).isAppearanceLightNavigationBars= false

用这个方法的时候会导致状态栏字体变成白色,目前我的解决办法是重新再设置一次状态栏字体颜色,如果你有更好的解决方法欢迎在评论区留言。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值