Android Jetpack Compose 沉浸式状态栏的实现

慈云数据 1年前 (2024-04-05) 技术支持 109 0

目录

  • 概述
  • 效果展示
  • 代码实现
    • 方法一
    • 方法二
    • 总结

      概述

      说到沉浸式状态栏,很多小伙伴可能不太熟悉,其实让Android的状态栏的颜色和APP的主题颜色相同,给人感觉状态栏和APP就是一体的。沉浸式的状态栏让页面看起来更舒服,实现沉浸式状态栏也很简单,首先就是配置主题,然后设置状态栏的颜色,之前的博客中实现沉浸式状态栏是通过将状态栏的颜色设置成页面背景的颜色,这样状态栏就和背景融为一体了,但是这种办法在每个页面都需要设置一遍,非常费力,最好的 方式就是将状态栏设置成透明的颜色,然后将我们的页面"顶"到屏幕的顶部,而不是位于状态栏下面。下面就是实现沉浸式状态栏的方法

      效果展示

      如果没有实现沉浸式状态栏的界面如下所示:

      在这里插入图片描述

      我们可以看到状态栏的颜色和我们的页面背景色不相同,而且状态栏的颜色还会随着手机的不同而不同,这让界面看起来很不协调。而加了沉浸式状态栏后,效果如下:

      在这里插入图片描述

      我们发现加入沉浸式状态栏后界面和状态栏的颜色就融为一体了,不管是啥品牌的手机展示的效果都是一样的,这样就会让我们的界面看起来比较舒服。

      代码实现

      实现沉浸式状态栏有两种方法,推荐使用方法二,不用额外引入库。

      方法一

      实现沉浸式状态栏我们首先需要引入一个库:

       // 系统UI控制库,实现沉浸式状态栏
          implementation("com.google.accompanist:accompanist-systemuicontroller:0.31.0-alpha")
      

      使用这个库我们可以设置系统状态栏的颜色,查看状态栏和导航栏是否显示等功能。引入库后我们需要给我们应用添加一个主题。

      在这里插入图片描述

      主题的内容如下:

      注意:设置主题时,我们需要使用包含NoActionBar的主题,否则我们的界面中会多出一个系统的ActionBar

      
          
      
      

      主题的文件位置如下图所示:

      在这里插入图片描述

      配置完主题后我们就可以去修改系统状态栏的颜色了。

      class MainActivity : ComponentActivity() {
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContent {
                  ImmersiveBarTheme {
                      // A surface container using the 'background' color from the theme
                      enableEdgeToEdge()
                      val systemUiController = rememberSystemUiController()
                      SideEffect {
                          // 因为我们目前没有暗色主题的UI,所以都是亮色主题UI,我们默认使用暗色的状态栏ICON
                          // ,防止出现标题栏字体颜色和UI背景融合的情况
                          systemUiController.setSystemBarsColor(Color.Transparent, darkIcons = true)
                          //window.statusBarColor = Color.Transparent.toArgb()
                      }
                      Surface(
                          modifier = Modifier.fillMaxSize(),
                          color = MaterialTheme.colorScheme.background
                      ) {
                          Image(
                              painter = painterResource(R.drawable.m11),
                              contentDescription = null,
                              contentScale = ContentScale.Crop,
                              modifier = Modifier.fillMaxSize()
                          )
                      }
                  }
              }
          }
      }
      

      上面的代码中实现沉浸式状态栏的主要代码为

        enableEdgeToEdge()
        val systemUiController = rememberSystemUiController()
        SideEffect {
            // 因为我们目前没有暗色主题的UI,所以都是亮色主题UI,我们默认使用暗色的状态栏ICON
            // ,防止出现标题栏字体颜色和UI背景融合的情况
            // darkIcons 的值控制状态栏显示的图标字体样式
            systemUiController.setSystemBarsColor(Color.Transparent, darkIcons = true)
            //window.statusBarColor = Color.Transparent.toArgb()
        }
      

      首先enableEdgeToEdge是让我们的界面可以”顶“到屏幕的最顶端,然后我们使用systemUiController将状态栏的颜色设置成透明的就可以实现沉浸式状态栏了,这里需要注意,我们设置状态栏颜色时需要放到SideEffect 或者是LaunchedEffect副作用API中,这样状态栏颜色才能设置成功,否者颜色会设置不成功导致无法实现沉浸式状态栏。这两个副作用API感兴趣的小伙伴可以去百度下,这里就不展开说了。

      方法二

      方法二是现在推荐的方式,使用也很简单,我直接贴代码:

      class MainActivity: ComponentActivity() {
          private val TAG = "MainActivity==>" 
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              enableEdgeToEdge()
              setContent {
                  val darkTheme = isSystemInDarkTheme()
                  DisposableEffect(darkTheme) {
                      enableEdgeToEdge(
                          statusBarStyle = SystemBarStyle.auto(
                              android.graphics.Color.TRANSPARENT,
                              android.graphics.Color.TRANSPARENT,
                          ) {darkTheme},
                          navigationBarStyle = SystemBarStyle.auto(
                              lightScrim,
                              darkScrim,
                          ) { darkTheme },
                      )
                      onDispose {}
                  }
                  Column(
                      modifier = Modifier
                          .background(Color.White)
                          .fillMaxWidth()
                          .fillMaxHeight()
                          .statusBarsPadding()
                  ) {
                      // 显示你的UI
                  }
              }
          }
          override fun onConfigurationChanged(newConfig: Configuration) {
              Log.i(TAG, "onConfigurationChanged: $newConfig")
              super.onConfigurationChanged(newConfig)
          }
          private val lightScrim = android.graphics.Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
          private val darkScrim = android.graphics.Color.argb(0x80, 0x1b, 0x1b, 0x1b)
      }
      

      总结

      本文主要介绍了在Android Compose下沉浸式状态栏的实现方法,实现沉浸式状态栏还有其他各种各样的方式,这里只是提供了一种,仅供参考。我们如果不想引入设置系统状态栏颜色的库,我们也可以去看下设置系统状态栏颜色使用的系统API,然后自己在代码中实现即可。如果读者有更好的沉浸式状态栏的实现方式,欢迎评论区讨论

微信扫一扫加客服

微信扫一扫加客服