You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中为特定Composable实现透明状态栏/导航栏

实现单个Composable的透明状态栏/导航栏方案

核心思路是在目标Composable生命周期内临时修改系统UI状态,离开时恢复原有配置——因为系统UI设置是全局的,必须通过副作用完成状态的切换与还原。

步骤1:封装状态保存与恢复逻辑

用DisposableEffect绑定Composable的生命周期,进入时记录当前系统UI参数,销毁时自动恢复:

@Composable
fun TransparentSystemUIScreen(content: @Composable () -> Unit) {
    val context = LocalContext.current
    val window = (context as Activity).window

    // 保存原有系统UI状态
    val originalStatusBarColor = window.statusBarColor
    val originalNavigationBarColor = window.navigationBarColor
    val originalStatusBarIconsLight = window.insetsController?.isAppearanceLightStatusBars
    val originalNavigationBarIconsLight = window.insetsController?.isAppearanceLightNavigationBars

    // 进入Composable时设置透明UI
    DisposableEffect(Unit) {
        // 设置状态栏和导航栏为透明
        window.statusBarColor = Color.TRANSPARENT
        window.navigationBarColor = Color.TRANSPARENT

        // 根据页面背景设置图标颜色(示例:深色背景用浅色图标)
        window.insetsController?.apply {
            isAppearanceLightStatusBars = false
            isAppearanceLightNavigationBars = false
        }

        // 离开时恢复原有状态
        onDispose {
            window.statusBarColor = originalStatusBarColor
            window.navigationBarColor = originalNavigationBarColor
            originalStatusBarIconsLight?.let {
                window.insetsController?.isAppearanceLightStatusBars = it
            }
            originalNavigationBarIconsLight?.let {
                window.insetsController?.isAppearanceLightNavigationBars = it
            }
        }
    }

    // 自动适配内边距,避免内容被状态栏/导航栏遮挡
    val windowInsets = rememberWindowInsetsPaddingValues(
        WindowInsets.statusBars,
        WindowInsets.navigationBars
    )
    Box(modifier = Modifier.padding(windowInsets)) {
        content()
    }
}

步骤2:在目标Composable中使用

直接把需要透明UI的页面内容包裹在这个封装组件里:

@Composable
fun MyImmersiveScreen() {
    TransparentSystemUIScreen {
        // 这里放你的沉浸式内容,比如全屏图片、深色背景页面
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.DarkGray)
        ) {
            Text(
                text = "仅此页启用透明系统栏",
                color = Color.White,
                modifier = Modifier.align(Alignment.Center)
            )
        }
    }
}

关键细节提醒

  • 版本兼容:如果要支持API 29及以下,需补充旧版API处理(比如window.decorView.systemUiVisibility),用Build.VERSION.SDK_INT做版本判断即可。
  • 图标可见性:根据页面背景色动态调整isAppearanceLightStatusBars,确保状态栏/导航栏图标与背景有足够对比度。
  • 内边距不要写死:必须用WindowInsets自动计算系统栏高度,适配不同机型的刘海屏、挖孔屏。

内容的提问来源于stack exchange,提问作者IamAyanMishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:26:05