Android应用暗黑模式清除后台重新打开后不生效问题求助
问题复现相关截图
- 亮色模式1
- 亮色模式2
- 暗黑模式1
- 暗黑模式2
问题描述
点击抽屉布局的设置按钮进入暗黑模式设置页,点击暗黑模式开关后全应用成功生效暗黑模式;但将应用从最近任务后台清除后重新打开,首页自动恢复为亮色模式,此时再从抽屉布局进入暗黑模式设置页,页面又会自动应用暗黑模式。
现有实现代码
const val FIRST_START = "FirstStart" const val NIGHT_MODE = "NightMode" const val PREF = "AppSettingsPrefs" class language_settings : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) loadLocate() setContentView(R.layout.activity_language_settings) val appSettingsPrefs: SharedPreferences = getSharedPreferences(PREF, 0) val isNightModeOn: Boolean = appSettingsPrefs.getBoolean(NIGHT_MODE, false) val isFirstStart: Boolean = appSettingsPrefs.getBoolean(FIRST_START,false) val editor: SharedPreferences.Editor = appSettingsPrefs.edit() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isFirstStart ){ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) } else{ when { isNightModeOn -> { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) } else -> { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) } } } btnSwitch.setOnClickListener { if (isNightModeOn) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) editor.putBoolean(FIRST_START, false) editor.putBoolean(NIGHT_MODE, false) editor.apply() recreate() } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) editor.putBoolean(FIRST_START, false) editor.putBoolean(NIGHT_MODE, true) editor.apply() recreate() } } } }
问题原因
你只在设置页面的onCreate方法里执行了读取本地存储、设置全局暗黑模式的逻辑。应用冷启动时首先加载的是首页Activity,此时没有触发暗黑模式设置逻辑,默认使用亮色模式。等你跳转进入设置页时,设置页的onCreate执行,才会读取存储的配置设置全局暗黑模式,整个应用才会切换为暗黑样式。
另外现有设置页代码还有个小问题:isNightModeOn是在onCreate时一次性读取的常量,点击开关修改存储值后没有更新这个变量,下次点击开关时判断逻辑会出错。
解决方法
步骤1:自定义全局Application类,统一初始化暗黑模式
class MyApp: Application() { // 把三个常量放在这里也可以,或者单独放到公共配置文件 companion object { const val FIRST_START = "FirstStart" const val NIGHT_MODE = "NightMode" const val PREF = "AppSettingsPrefs" } override fun onCreate() { super.onCreate() val appSettingsPrefs = getSharedPreferences(PREF, 0) val isNightModeOn = appSettingsPrefs.getBoolean(NIGHT_MODE, false) val isFirstStart = appSettingsPrefs.getBoolean(FIRST_START,false) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isFirstStart ){ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) } else { AppCompatDelegate.setDefaultNightMode( if (isNightModeOn) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO ) } } }
步骤2:在AndroidManifest.xml中注册自定义Application
找到manifest的application标签,添加android:name=".MyApp"属性即可,其余原有配置不用修改:
<application android:name=".MyApp" ...其余原有配置不变... > ...Activity等注册内容不变... </application>
步骤3:优化设置页的开关逻辑(可选,解决重复点击异常问题)
btnSwitch.setOnClickListener { // 直接读取当前全局模式做判断,避免变量缓存导致的逻辑错误 val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK val newNightModeOn = currentNightMode != Configuration.UI_MODE_NIGHT_YES AppCompatDelegate.setDefaultNightMode( if (newNightModeOn) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO ) val editor = getSharedPreferences(PREF, 0).edit() editor.putBoolean(FIRST_START, false) editor.putBoolean(NIGHT_MODE, newNightModeOn) editor.apply() recreate() }
内容的提问来源于stack exchange,提问作者Kalyan Mishra
相关产品推荐
相关产品推荐

