Jetpack Compose切换主题时图标颜色/图标不更新问题求助
问题描述
应用内有主题切换页面,提供浅色主题、深色主题、跟随系统三个选项。点击选项后主题可正常切换,但图标颜色未随之变化。已准备深色和浅色两种Drawable图标文件,Logcat显示theme.value输出正确(深色主题输出true,浅色输出false),问题仍未解决。
相关代码
ThemeScreen
val isSystemDarkTheme = isSystemInDarkTheme() Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally ) { SelectableTitleWithIcon( title = stringResource(id = R.string.karanlik), shouldShowImage = state.selectedThemeType == ThemeType.DarkTheme, onClick = { onChangeThemeType(ThemeType.DarkTheme) saveThemeChoose(ThemeType.DarkTheme) saveDarkTheme(true) }) CustomDivider(startPadding = 15.dp, endPadding = 15.dp) SelectableTitleWithIcon( title = stringResource(id = R.string.aydinlik), shouldShowImage = state.selectedThemeType == ThemeType.LightTheme, onClick = { onChangeThemeType(ThemeType.LightTheme) saveThemeChoose(ThemeType.LightTheme) saveDarkTheme(false) }) CustomDivider(startPadding = 15.dp, endPadding = 15.dp) SelectableTitleWithIcon( title = stringResource(id = R.string.sistem_ile_ayni), shouldShowImage = state.selectedThemeType == ThemeType.SystemTheme, onClick = { onChangeThemeType(ThemeType.SystemTheme) saveThemeChoose(ThemeType.SystemTheme) if (isSystemDarkTheme) saveDarkTheme(true) else saveDarkTheme(false) }) CustomDivider(startPadding = 15.dp, endPadding = 15.dp) }
ThemeScreenViewModel
@HiltViewModel class ThemeViewModel @Inject constructor( private val dataStoreUtil: DataStoreUtil, private val dataStoreHelper: PreferenceDataStoreHelper ) : ViewModel() { private val _state = MutableStateFlow(ThemeScreenState()) val state: StateFlow<ThemeScreenState> = _state.asStateFlow() fun onChangeThemeType(themeType: ThemeType){ _state.update { it.copy( selectedThemeType = themeType ) } } fun saveThemeChoose(themeType: ThemeType) { viewModelScope.launch { dataStoreHelper.putPreference(PreferenceDataStoreConstants.THEME_CHOOSE, themeType.name) } } fun saveDarkTheme(isDarkTheme: Boolean) { viewModelScope.launch { dataStoreUtil.saveTheme(isDarkTheme) } } } sealed class ThemeType(val name: String) { object DarkTheme : ThemeType("dark_theme") object LightTheme : ThemeType("light_theme") object SystemTheme : ThemeType("system_theme") object Default : ThemeType("default") companion object { fun fromName(name: String): ThemeType { return when (name) { DarkTheme.name -> DarkTheme LightTheme.name -> LightTheme SystemTheme.name -> SystemTheme Default.name -> Default else -> SystemTheme } } } } data class ThemeScreenState( val selectedThemeType: ThemeType = ThemeType.Default )
MainActivity
@AndroidEntryPoint class MainActivity : ComponentActivity() { private lateinit var dataStoreUtil: DataStoreUtil override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) dataStoreUtil = DataStoreUtil(applicationContext) val systemTheme = when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { Configuration.UI_MODE_NIGHT_YES -> { true } Configuration.UI_MODE_NIGHT_NO -> { false } else -> { false } } setContent { val theme = dataStoreUtil.getTheme(systemTheme).collectAsState(initial = systemTheme) println("theme->"+theme.value) AppTheme(darkTheme = theme.value) { ...
AppTheme
private val DarkColors = darkColors( background = md_theme_dark_background, surface = md_theme_dark_surface, primary = md_theme_dark_primary, primaryVariant = md_theme_dark_primary_variant, onPrimary = md_theme_dark_onPrimaryContainer, secondary = md_theme_dark_primary, onSecondary = md_theme_dark_onPrimaryContainer, secondaryVariant = md_theme_dark_secondaryContainer, ) private val LightColors = lightColors( background = md_theme_light_background, surface = md_theme_light_surface, primary = md_theme_light_primary, primaryVariant = md_theme_light_primary_variant, onPrimary = md_theme_light_onPrimaryContainer, secondary = md_theme_light_primary, onSecondary = md_theme_light_onPrimaryContainer, secondaryVariant = md_theme_light_primary_variant, ) @Composable fun AppTheme( darkTheme: Boolean = isSystemInDarkTheme(), dynamicColor: Boolean = true, content: @Composable () -> Unit ) { val colors = if (darkTheme) DarkColors else LightColors MaterialTheme( colors = colors, typography = MontSerratTypography(colors), content = content, ) }
相关资源截图
- 图标文件结构:

- 深色模式截图:

- 浅色模式截图:

排查方向建议
- 图标资源配置检查:确认深色图标放置在
drawable-night目录,浅色图标在drawable(或drawable-day)目录,且文件名完全一致。 - 图标加载方式检查:查看
SelectableTitleWithIcon组件中加载图标的代码,是否使用painterResource(id = R.drawable.your_icon),而非硬编码颜色或固定资源。 - 重组触发验证:主题切换后,确保Compose能触发重组。可检查
dataStoreUtil.getTheme()是否正确监听数据变化,保证主题状态更新时通知Composable。 - 系统主题同步处理:选择“跟随系统”时,需实时监听系统主题变化,不能仅在
onCreate中获取一次状态,可通过isSystemInDarkTheme()实时获取系统主题。
内容的提问来源于stack exchange,提问作者NewPartizal
相关产品推荐
相关产品推荐

