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
相关产品推荐
相关产品推荐

