沉浸式

Posted by OOFTF Blog on April 16, 2021

去除ActionBar

  1. Activity requestWindowFeature(Window.FEATURE_NO_TITLE) 这种方式并不起作用
  2. hide
    1
    2
    
     Activity.actionBar?.hide()
     Activity.supportActionBar?.hide()
    

    这种方式虽然可以隐藏掉 ActionBar 但是在5.0(我只试了5.0)的版本中,《android:fitsSystemWindows=”true”》 属性会连隐藏掉 的 ActionBar 的空间也算进去

  3. 采用 NoActionBar 的 theme
  4. 设置style
    1
    2
    3
    4
    
     <style name="NoActionBar" >
         <item name="windowActionBar">false</item>
         <item name="windowNoTitle">true</item>
     </style>
    
    1
    
     Activity.theme.applyStyle(R.style.NoActionBar,true)
    

结论:方案3和方案4,是目前来说兼容性最好的方案,其他方案都有一些兼容性问题

设置透明状态栏

  1. 动态代码控制:Activity.window.statusBarColor = Color.TRANSPARENT
  2. 在主题中添加 statusBarColor属性
    1
    
     <item name="android:statusBarColor" >#00000000</item>
    
  3. 使用 Theme.applyStyle
    1
    2
    3
    
     <style name="transparentStatusBar" >
         <item name="android:statusBarColor" >#00000000</item>
     </style>
    
    1
    
     Activity.theme.applyStyle(R.style.transparentStatusBar, true)
    
  4. 在Android 12 荣耀手50机上设置状态栏颜色的时候需要使用 getWindow().setStatusBarColor(Color.parseColor(“#00FFFFFF”)); 不要使用 getWindow().setStatusBarColor(Color.parseColor(“#00000000”)); 不要使用 getWindow().setStatusBarColor(Color.TRANSPARENT);

修改 StatusBar 背景色

分两种情况

1. 状态栏颜色为不透明状态

这时候状态栏色颜色为 statusBarColor 的颜色,所以这时候只要修改 StatusBar 的颜色就可以了,具体操作步骤可参考《设置透明状态栏》

优点:理解起来比较简单,操作起来也比较简单 缺点:只能设置纯色,无法设置图片和渐变色

2. 状态栏颜色为透明状态

  1. 不修改 decorFitsSystemWindows ,默认为 true 默认情况下 decorFitsSystemWindows 设置为 true,所以 StatusBar 在透明状态栏情况下,显示的颜色为 DecorView 的背景色,因此我们只要设置 DecorView 的背景色就可以修改 StatusBar 背景色

    1
    
     Activity.window.setBackgroundDrawable(ColorDrawable(Color.WHITE))
    

    总结:因为状态栏只占背景的一小部分,所以如果要展示图片或者渐变色并不好控制,如果只是设置纯色又不如直接设置设置 statusBarColor 简单,所以并不推荐

  2. 修改 decorFitsSystemWindows 为 false 当我们修改 decorFitsSystemWindows 为 false 的时候,我们通过 setContentView 设置的布局就会延展到 StatusBar 和 NavigationBar 下面,这时候我们可以设置 View 的颜色来变相修改 StatusBar 和 NavigationBar 的背景颜色

    1
    2
    
     // 需要添加 implementation 'androidx.core:core:1.6.0-rc01'
     WindowCompat.setDecorFitsSystemWindows(window, false)
    

    总结:这种方式比较灵活,但是要处理的问题也是最多的,如果使用这种就要处理好下面两个问题

    1. 当我们将 decorFitsSystemWindows 设置为 false 时,如何解决 StatusBar 遮挡布局问题

  3. 对需要将 background 作为状态栏的控件,添加 <android:fitsSystemWindows=”true”>,需要注意的是这种方式,在 Android 5.0 的手机上,不支持多个控件同时设置这个属性,并且设置 fitsSystemWindows 后,原来的 padding 属性会失效
  4. 对需要将 background 作为状态栏的控件,添加和状态栏同样高度的 padding

2. 当我们将 decorFitsSystemWindows 设置为 false 时,如何解决,NavigationBar 遮挡布局问题

  1. 对底部控件或者跟布局添加 <android:fitsSystemWindows=”true”> 属性
  2. 对 activity.findViewById(android.R.id.content) 这个控件添加与 NavigationBar 同样高度的padding,要注意在横竖屏不同情况下 NavigationBar 所对应的 Padding 在不同的位置

修改 StatusBar 为 light 模式,也就是把文字改为黑色

1
2
3
4
5
6
7
8
9
10
11
12
// 第一种,这一种存在一个问题:退出到桌面然后再进入App ,会自动退出 light 模式
ViewCompat.getWindowInsetsController(window.decorView)?.isAppearanceLightStatusBars = true

// 第二种
View decorView = window.getDecorView();
int vis = decorView.getSystemUiVisibility();
if (isLightMode) {
    vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
    vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
decorView.setSystemUiVisibility(vis);

be care

  • decorFitsSystemWindows 为 false 时状态栏遮挡布局问题和 statusBarColor 没有关系,即使不是透明状态栏,将 decorFitsSystemWindows 设置为 false 状态栏同样会遮挡布局

  • android:fitsSystemWindows=”true” 在 Android 5.0 的手机上,不支持多个控件同时设置这个属性,并且设置 fitsSystemWindows 后,原来的 padding 属性会失效

  • android:fitsSystemWindows=”true” 在5.0(我只试了5.0)的版本中,《android:fitsSystemWindows=”true”》 属性会连隐藏掉 的 ActionBar 的空间也算进去

  • android:windowFullscreen = true 在非全面屏会导致不能全屏 可以添加如下代码,或者去除 windowFullScreen 属性
    1
    2
    3
    4
    5
    6
    7
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
      window.attributes.apply {
          layoutInDisplayCutoutMode =
              WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
          window.attributes = this
      }
    }
    
  • 想要内容全屏需要设置三个内容
    • FLAG_FULLSCREEN
    • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    • setDecorFitsSystemWindows