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
相关产品推荐
相关产品推荐

