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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:25:07