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

Android运行时用setIcon切换按钮图标失效,寻求解决方案

问题解决:夜间/日间模式切换按钮图标不更新

问题根源

你在设置按钮图标和文本后立刻调用recreate(),导致Activity直接重建,刚设置的UI状态还没来得及渲染就被重置。同时,初始化检测模式的逻辑和切换模式的逻辑没有分离,导致每次重建后重复执行错误的流程。

正确实现方案

1. 初始化时检测模式,设置按钮状态

在Activity创建阶段,仅根据当前系统模式设置按钮的图标和文本,不要在这里调用recreate():

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val modeButton = findViewById<Button>(R.id.mode)
    
    val nightFlag = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
    when (nightFlag) {
        Configuration.UI_MODE_NIGHT_YES -> {
            // 当前是夜间模式,按钮显示切换到日间的标识
            modeButton.icon = ContextCompat.getDrawable(this, R.drawable.lightmode)
            modeButton.text = "Light"
        }
        Configuration.UI_MODE_NIGHT_NO -> {
            // 当前是日间模式,按钮显示切换到夜间的标识
            modeButton.icon = ContextCompat.getDrawable(this, R.drawable.darkmode)
            modeButton.text = "Night"
        }
    }
    
    // 绑定按钮点击的切换逻辑
    modeButton.setOnClickListener {
        switchNightMode()
    }
}

2. 单独实现模式切换逻辑

把切换模式的代码抽成独立方法,修改系统夜间模式配置后再调用recreate():

private fun switchNightMode() {
    val nightFlag = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
    val newMode = if (nightFlag == Configuration.UI_MODE_NIGHT_YES) {
        AppCompatDelegate.MODE_NIGHT_NO
    } else {
        AppCompatDelegate.MODE_NIGHT_YES
    }
    AppCompatDelegate.setDefaultNightMode(newMode)
    recreate()
}

额外注意事项

  • 确保R.drawable.darkmode和R.drawable.lightmode资源存在,且不要在drawable-night目录下放同名资源,避免被系统自动替换。
  • 如果使用MaterialButton,推荐用setIcon()方法设置图标,兼容性更好。
  • 禁止在初始化阶段调用recreate(),会导致Activity反复重建,既影响性能也会覆盖UI状态。

内容的提问来源于stack exchange,提问作者Nishu Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:41:12