Accompanist systemUiController的darkIcons在Android11亮色主题下不生效问题
问题现象
使用Accompanist systemUiController库时,亮色主题下设置darkIcons=false仅在Android 10及更低版本设备生效,Android 11设备上不生效。当前需求为深色状态栏下,状态栏前景/图标显示为白色。
暗色主题下darkIcons参数无论设置为true还是false,均能正常生效。
排查说明
曾尝试脱离生命周期监听逻辑直接设置状态栏颜色,问题仍复现。
相关代码
状态栏基础配置代码
val systemUiController = rememberSystemUiController() systemUiController.setStatusBarColor(color=statusBarColor,darkIcons=false)
主题配置代码(Theme.kt)
private val LightBase = ASBTheme( material = lightColors( background = FigmaPrimaryWhite, onBackground = FigmaTextBlack, surface = FigmaPrimaryWhite, onSurface = FigmaTextBlack, primary = FigmaSecondaryAvastBlue, error = FigmaStatusPink, ), textColorLabel = FigmaSecondaryAvastPurple, colorAccent = FigmaPrimaryGreen, ... // 其余自定义颜色配置 ) private val DarkBase = ASBTheme( material = darkColors( background = FigmaPrimaryBlackBg, onBackground = FigmaTextWhite, surface = FigmaSecondaryAvastBlueDark, onSurface = FigmaTextWhite, primary = FigmaSecondaryBlackDark, error = FigmaStatusPink ), textColorLabel = FigmaSecondaryAvastPurpleBright, colorAccent = FigmaStatusGreen, ... // 其余自定义颜色配置 ) private val LocalAsbTheme = staticCompositionLocalOf { LightBase } var navBarColor: Color? = null var statusBarColor: Color? = null @Composable fun ASBTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { val colors = if (darkTheme) { DarkBase } else { LightBase } if (darkTheme) { navBarColor = DarkBase.background statusBarColor = DarkBase.primary } else { navBarColor = LightBase.background statusBarColor = LightBase.primary } SetBarsTheme(statusBarColor!!, navBarColor!!) CompositionLocalProvider( LocalAsbTheme provides colors, ) { MaterialTheme( colors = colors.material, content = content, ) } } val MaterialTheme.asbTheme: ASBTheme @Composable @ReadOnlyComposable get() = LocalAsbTheme.current
状态栏样式设置方法
@Composable fun SetBarsTheme( statusBarColor: Color, navigationBarColor: Color, darkIcons:Boolean=false, ) { val lifecycleOwner = LocalLifecycleOwner.current val systemUiController = rememberSystemUiController() DisposableEffect(lifecycleOwner) { val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_RESUME) { systemUiController.setStatusBarColor(color=statusBarColor,darkIcons) systemUiController.setNavigationBarColor(color=navigationBarColor) } } lifecycleOwner.lifecycle.addObserver(observer) onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } } }
解决方案
这个问题是Android 11调整了状态栏外观控制优先级,和旧版本Accompanist的适配逻辑冲突导致,可按如下步骤修复:
- 升级Accompanist依赖到0.24.0及以上版本,该版本已修复Android 11下
darkIcons配置不生效的问题,注意版本需与项目使用的Compose版本匹配。 - 修正
SetBarsTheme方法的参数传递逻辑,当前调用时未主动传入darkIcons参数,默认值固定为false,需根据主题和状态栏颜色动态传入对应值:
修改ASBTheme中调用SetBarsTheme的代码:
SetBarsTheme( statusBarColor = statusBarColor!!, navigationBarColor = navBarColor!!, // 亮色主题下状态栏为深色,图标设为白色(darkIcons=false);暗色主题同理 darkIcons = !darkTheme && statusBarColor.luminance() > 0.5 // 如亮色主题状态栏为浅色,可直接设置为darkIcons = !darkTheme )
- 如升级依赖后仍有问题,可添加原生API作为兜底适配:
在SetBarsTheme中调用setStatusBarColor后添加如下代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val window = LocalContext.current as Activity window.insetsController?.setSystemBarsAppearance( if (darkIcons) WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS else 0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS ) }
内容的提问来源于stack exchange,提问作者Tiberiu Paduraru
相关产品推荐
相关产品推荐

