如何在Jetpack Compose中隐藏导航栏和状态栏?

16
我已经知道了使用Accompanist库来更改导航栏和状态栏颜色的方法。目标是完全隐藏它们。

请提供足够的代码,以便他人更好地理解或重现问题。 - Community
5个回答

32

SystemUiController具有用于系统栏可见性的getter/setter方法:

val systemUiController: SystemUiController = rememberSystemUiController()

systemUiController.isStatusBarVisible = false // Status bar
systemUiController.isNavigationBarVisible = false // Navigation bar
systemUiController.isSystemBarsVisible = false // Status & Navigation bars

3
有没有办法在这个项目中实现 Android 的“粘性沉浸式模式”? - Stephen
我没有深入研究过这个问题,但上次尝试时我无法弄清楚。 - Yasan
2
WindowCompat.getInsetsController(window,window.decorView).apply { if (isTrue) systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE } - Tarif Chakder
3
不要忘记添加 -> implementation "com.google.accompanist:accompanist-systemuicontroller:0.28.0"。 - Amal

2
由于accompanist-systemuicontroller已被弃用,这里提供另一个解决方案。
使用一次性的:
@Composable
fun HideSystemBars() {
    val context = LocalContext.current

    DisposableEffect(Unit) {
        val window = context.findActivity()?.window ?: return@DisposableEffect onDispose {}
        val insetsController = WindowCompat.getInsetsController(window, window.decorView)

        insetsController.apply {
            hide(WindowInsetsCompat.Type.statusBars())
            hide(WindowInsetsCompat.Type.navigationBars())
            systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        }

        onDispose {
            insetsController.apply {
                show(WindowInsetsCompat.Type.statusBars())
                show(WindowInsetsCompat.Type.navigationBars())
                systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
            }
        }
    }
}

fun Context.findActivity(): Activity? {
    var context = this
    while (context is ContextWrapper) {
        if (context is Activity) return context
        context = context.baseContext
    }
    return null
}

或者没有一个:
val insetsController = WindowCompat.getInsetsController(window, window.decorView)

insetsController.apply {
    hide(WindowInsetsCompat.Type.statusBars())
    hide(WindowInsetsCompat.Type.navigationBars())
    systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}

2
隐藏单个Composable屏幕的状态栏。
DisposableEffect(key1 = true){
    systemUiController.isStatusBarVisible = false // Status bar
    onDispose {
        systemUiController.isStatusBarVisible = true // Status bar
    }
}

还要添加这个依赖。
    implementation("com.google.accompanist:accompanist-systemuicontroller:0.31.2-alpha")

1
伴奏库已被弃用。 - undefined

0

你可以在你的MainActivity中直接这样做

override fun onResume() {
    super.onResume()
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
}

override fun onStart() {
    super.onStart()
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
}

看起来不错,但需要记住这是将组合代码与传统系统的代码混合在一起。只要可能,我更喜欢只使用一个UI概念。 - Daniel Weidensdörfer
是的,你说得对,但有时我们可以使用传统系统中的代码。在这种情况下,我看不出有什么问题。 - Giorgi
1
@DanielWeidensdörfer 现在还不清楚 Compose 是否打算接管这些事情。它肯定不能控制状态/导航栏的绘制,所以不确定为什么我们会认为它应该控制它们的显示或隐藏。另一件事是,如果 Compose 打算这样做,为什么它没有呢?上面链接的 SystemUiController 库并不是 Compose 的一部分,它最终只是一个使用 WindowInsertDecorView.systemUiVisibility 的包装器。 - Jeffrey Blattman

0

还要添加LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES来隐藏刘海屏

val window = (view.context as Activity).window
val layoutParams = window.attributes

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
  layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
window.attributes = layoutParams

添加可组合性,以便添加填充,最好在 TopAppBar 中。

modifier = Modifier.windowInsetsPadding(WindowInsets.displayCutout)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接