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

Android API 35+ 系统导航栏颜色修改失效问题求助

Android API 35+ 系统导航栏颜色修改失效问题求助

大家好,我最近在调整App的系统导航栏样式时遇到了一个头疼的问题,折腾了好几天都没找到根因,想请教下社区里的大佬们有没有解决方案?

问题具体是这样的:

  • 深色模式下,系统导航栏是透明的,这符合预期(其实我更希望它和底部自定义导航栏颜色保持一致);
  • 但切换到浅色模式后,系统导航栏直接变成纯白色,完全无视我设置的透明或自定义颜色。

我了解到Android 35之后系统对导航栏加了一层保护机制,但按照官方文档的说法,设置透明的话应该能让自定义内容透出来才对?目前还没测试API高于35的设备,先集中解决当前版本的问题。

用布局检查器排查时,能看到导航栏的区域是存在的,但颜色就是不生效。我的页面背景是铺满整个屏幕(包含状态栏和导航栏区域)的,比如我把背景设为黄色时,深色模式下状态栏和导航栏都能正确显示这个黄色背景,但浅色模式下导航栏还是死死的白色,完全不受影响。

下面是我MainActivity的完整代码:

class MainActivity : AppCompatActivity() {
    private val startupViewModel: StartupViewModel by viewModel()
    private val inAppUpdateManager: InAppUpdateManager by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        installSplashScreen()
        super.onCreate(savedInstanceState)

        var themeSettings by mutableStateOf(
            ThemeSettings(
                darkTheme = false,
                dynamicColor = false
            )
        )

        inAppUpdateManager.check(this)

        lifecycleScope.launch {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                combine(
                    isSystemInDarkTheme(),
                    startupViewModel.state
                ) { systemDark, uiState ->
                    ThemeSettings(
                        darkTheme = when (uiState.theme) {
                            Theme.SYSTEM -> systemDark
                            Theme.LIGHT -> false
                            Theme.DARK -> true
                        },
                        dynamicColor = uiState.dynamicColors
                    )
                }.onEach { themeSettings = it }
                 .map { it.darkTheme }
                 .distinctUntilChanged()
                 .collect { darkTheme ->
                     enableEdgeToEdge(
                         statusBarStyle = SystemBarStyle.auto(
                             lightScrim = Color.TRANSPARENT,
                             darkScrim = Color.TRANSPARENT,
                         ) { darkTheme },
                         navigationBarStyle = SystemBarStyle.auto(
                             lightScrim = Color.TRANSPARENT,
                             darkScrim = Color.TRANSPARENT,
                         ) { darkTheme }
                     )
                 }
            }
        }

        setContent {
            Theme(
                darkTheme = themeSettings.darkTheme,
                dynamicColor = themeSettings.dynamicColor
            ) {
                val state = startupViewModel.state.collectAsStateWithLifecycle()
                Background {
                    if (state.value.isLoading) {
                        StartupScreen(
                            showSkip = { state.value.showSkip },
                            onSkip = { startupViewModel.skipFetching() }
                        )
                    } else {
                        NavigationRoot(startDestination = state.value.startDestination)
                    }
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        inAppUpdateManager.onResume(this)
    }
}

private val lightScrim = Color.argb(0xe6, 0xFF, 0xFF, 0x00)
private val darkScrim = Color.argb(0xe6, 0xFF, 0xFF, 0x00)

@Immutable
private data class ThemeSettings(
    val darkTheme: Boolean,
    val dynamicColor: Boolean,
)

还有我设置全局背景的Background Composable代码:

@Composable
fun Background(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    val primary = MaterialTheme.colorScheme.surface
    val secondary = MaterialTheme.colorScheme.surfaceContainer
    val gradient = remember(primary, secondary) {
        Brush.verticalGradient(colors = listOf(primary, secondary))
    }

    Box(
        modifier = modifier.fillMaxSize()
    ) {
        Surface(
            color = Color.Transparent,
            modifier = Modifier
                .matchParentSize()
                .background(gradient)
        ) {
            CompositionLocalProvider(LocalAbsoluteTonalElevation provides 0.dp) {
                content()
            }
        }

        if (Build.VERSION.SDK_INT >= 35) {
            Box(
                modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .fillMaxWidth()
                    .zIndex(Float.MAX_VALUE)
                    .windowInsetsBottomHeight(WindowInsets.navigationBars)
                    .background(MaterialTheme.colorScheme.surfaceContainer)
            )
        }
    }
}

已解决!更新于2025.07.29

多亏了Mofe Ejegi的提示,我终于把问题搞定了!现在不仅渐变背景能正常覆盖整个屏幕,系统导航栏的颜色(包括里面的图标样式)也能跟着主题正确切换了。下面是修改后的最终代码:

修改后的Background Composable:

@Composable
fun Background(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    val primary = MaterialTheme.colorScheme.surface
    val secondary = MaterialTheme.colorScheme.surfaceContainer
    val gradient = remember(primary, secondary) {
        Brush.verticalGradient(colors = listOf(primary, secondary))
    }

    Box(
        modifier = modifier
            .fillMaxSize()
    ) {
        Surface(
            color = Color.Transparent,
            modifier = modifier
                .fillMaxSize()
                .background(gradient)
        ) {
            CompositionLocalProvider(LocalAbsoluteTonalElevation provides 0.dp) {
                content()
            }
        }

        Box(
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .fillMaxWidth()
                .windowInsetsBottomHeight(WindowInsets.navigationBars)
                .background(MaterialTheme.colorScheme.surfaceContainer)
        )
    }
}

修改后的MainActivity代码:

class MainActivity : AppCompatActivity() {
    private val startupViewModel: StartupViewModel by viewModel()
    private val inAppUpdateManager: InAppUpdateManager by inject()
    private lateinit var updateLauncher: ActivityResultLauncher<IntentSenderRequest>

    override fun onCreate(savedInstanceState: Bundle?) {
        installSplashScreen()
        var themeSettings by mutableStateOf(
            ThemeSettings(
                darkTheme = false,
                dynamicColor = false
            )
        )

        lifecycleScope.launch {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                combine(
                    isSystemInDarkTheme(),
                    startupViewModel.state
                ) { systemDark, uiState ->
                    ThemeSettings(
                        darkTheme = when (uiState.theme) {
                            Theme.SYSTEM -> systemDark
                            Theme.LIGHT -> false
                            Theme.DARK -> true
                        },
                        dynamicColor = uiState.dynamicColors
                    )
                }.onEach { themeSettings = it }
                 .map { it.darkTheme }
                 .distinctUntilChanged()
                 .collect { darkTheme ->
                     enableEdgeToEdge(
                         statusBarStyle = SystemBarStyle.auto(
                             lightScrim = Color.TRANSPARENT,
                             darkScrim = Color.TRANSPARENT,
                         ) { darkTheme },
                         navigationBarStyle = SystemBarStyle.auto(
                             lightScrim = Color.TRANSPARENT,
                             darkScrim = Color.TRANSPARENT,
                         ) { darkTheme }
                     )
                 }
            }
        }

        setContent {
            Theme(
                darkTheme = themeSettings.darkTheme,
                dynamicColor = themeSettings.dynamicColor
            ) {
                val state = startupViewModel.state.collectAsStateWithLifecycle()
                Background {
                    if (state.value.isLoading) {
                        StartupScreen(
                            showSkip = { state.value.showSkip },
                            onSkip = { startupViewModel.skipFetching() }
                        )
                    } else {
                        NavigationRoot(startDestination = state.value.startDestination)
                    }
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        inAppUpdateManager.onResume(this)
    }
}

@Immutable
private data class ThemeSettings(
    val darkTheme: Boolean,
    val dynamicColor: Boolean,
)

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 13:28:11