Material3 ColorScheme实现动态颜色时显示异常(颜色发灰)
问题:Compose中MaterialTheme.colorScheme引用自定义颜色发灰不准确
问题现象
开发左侧带AppBar的应用时,重构代码使用MaterialTheme.colorScheme.primary作为AppBar背景、MaterialTheme.colorScheme.tertiary作为选中按钮颜色,显示颜色发灰且与自定义值不符;但直接引用Color.kt中的PrimaryLightColor、selectedLight时,颜色显示正常。
原因分析
问题出在Theme.kt的颜色逻辑中:当dynamicColor=true且设备SDK版本≥Android 12(API 31)时,代码会优先使用系统提供的dynamicLightColorScheme(context)或dynamicDarkColorScheme(context)生成颜色方案,这会直接覆盖你自定义的LightColorScheme,导致MaterialTheme.colorScheme取到的是系统动态生成的颜色,而非你定义的十六进制值。
解决方案
根据需求选择以下方案:
方案1:关闭动态颜色(快速解决)
如果不需要系统动态颜色适配,直接将dynamicColor的默认值设为false,强制使用自定义的颜色方案:
@Composable fun KalanikethanCICTheme( darkTheme: Boolean = isSystemInDarkTheme(), // 关闭系统动态颜色 dynamicColor: Boolean = false, content: @Composable () -> Unit ) { val colorScheme = if (darkTheme) { // 替换为你自定义的深色主题ColorScheme DarkColorScheme } else { LightColorScheme } MaterialTheme( colorScheme = colorScheme, typography = Typography, content = content ) }
注意:需要先定义DarkColorScheme以支持深色主题,示例如下:
private val DarkColorScheme = darkColorScheme( primary = Color(0xFF135897), tertiary = Color(0xFF1b69b2), background = Color(0xFF121212) )
方案2:保留动态颜色并叠加自定义色
若想保留系统动态颜色的同时,强制部分颜色使用自定义值,可以在生成动态颜色方案后,用copy()方法覆盖指定颜色:
@Composable fun KalanikethanCICTheme( darkTheme: Boolean = isSystemInDarkTheme(), dynamicColor: Boolean = true, content: @Composable () -> Unit ) { val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current if (darkTheme) { dynamicDarkColorScheme(context).copy( primary = Color(0xFF135897), // 深色主题自定义primary tertiary = Color(0xFF1b69b2) // 深色主题自定义选中色 ) } else { dynamicLightColorScheme(context).copy( primary = PrimaryLightColor, tertiary = selectedLight ) } } darkTheme -> DarkColorScheme else -> LightColorScheme } MaterialTheme( colorScheme = colorScheme, typography = Typography, content = content ) }
验证修改
修改后重新运行应用,MaterialTheme.colorScheme.primary和tertiary会正确使用你定义的颜色,同时支持深色主题切换。
内容的提问来源于stack exchange,提问作者Shawarm0
相关产品推荐
相关产品推荐

