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

Android Studio主题切换与SharedPreferences持久化存储问题

主题切换+SharedPreferences持久化问题修复指导

问题描述

尝试在ActionBar添加主题切换选项,支持浅色/深色主题切换,并用SharedPreferences持久化设置以实现重启后保留主题。未添加SharedPreferences前可正常切换主题,添加后功能失效。

问题根源分析

  1. 存储Key不统一:切换浅色/深色主题时分别使用"light"和"dark"两个独立Key存储,导致读取时无法准确获取当前选中的主题配置
  2. 读取逻辑混乱:读取主题时的判断条件与存储逻辑不匹配,取值逻辑存在错误
  3. 主题设置时机错误:在setContentView()之后调用AppCompatDelegate.setDefaultNightMode(),主题切换不会生效,必须在加载布局前完成主题设置

修复方案

步骤1:统一SharedPreferences存储Key

切换主题时使用同一个Key(例如"selected_theme")存储当前选中的主题模式值,替代原有分Key存储的逻辑。

步骤2:修正主题读取与设置逻辑

在onCreate()中,先从SharedPreferences读取主题配置,在setContentView()之前完成主题设置,确保布局加载时使用正确的主题。

修正后的代码示例

MainActivity.kt 菜单点击逻辑修改

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val editor = App.sharedPreferences.edit()

    when(item.itemId){
        R.id.menuRead -> {
            Toast.makeText(this,"Pulling data from Room",Toast.LENGTH_SHORT).show()
        }
        R.id.menuDelete -> {
            Toast.makeText(this,"Deleting data from Room",Toast.LENGTH_SHORT).show()
            viewModel.deleteData()
        }
        R.id.lightTheme -> {
            Toast.makeText(this,"Switching to Light Theme!",Toast.LENGTH_SHORT).show()
            val lightMode = AppCompatDelegate.MODE_NIGHT_NO
            AppCompatDelegate.setDefaultNightMode(lightMode)
            editor.putInt("selected_theme", lightMode)
            editor.apply()
        }
        R.id.darkTheme -> {
            Toast.makeText(this,"Switching to Dark Theme!",Toast.LENGTH_SHORT).show()
            val darkMode = AppCompatDelegate.MODE_NIGHT_YES
            AppCompatDelegate.setDefaultNightMode(darkMode)
            editor.putInt("selected_theme", darkMode)
            editor.apply()
        }
    }
    return true
}

MainActivity.kt onCreate逻辑修改

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val viewModel : MainViewModel by viewModels()
    private val defaultTheme = AppCompatDelegate.MODE_NIGHT_NO
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 读取主题配置并设置,必须在setContentView之前执行
        val savedTheme = App.sharedPreferences.getInt("selected_theme", defaultTheme)
        AppCompatDelegate.setDefaultNightMode(savedTheme)
        
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        // 其他原有业务逻辑...
    }
}

额外优化建议

  • 可在Application类中定义主题相关常量,避免重复硬编码模式值
  • 若主题切换后未自动生效,可手动调用recreate()重启当前Activity(部分场景下setDefaultNightMode会自动触发重启,无需额外操作)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:30:51