我设计了一个主题设置片段让用户在主题之间进行选择。它将值写入 Preferences Datastore,然后 ViewModel 的观察者会观察到该数据存储区,并且主题会相应更改。但是,当我尝试从系统默认切换到暗模式时,观察者会进入一个循环。这就是我的观察者代码的样子:
viewModel.userPreferences.observe(viewLifecycleOwner) { theme ->
Log.d(TAG, theme.toString())//-> to know which value is in the Preferences
when (theme) {
AppCompatDelegate.MODE_NIGHT_NO -> lightThemeButton.isChecked = true
AppCompatDelegate.MODE_NIGHT_YES -> darkThemeButton.isChecked = true
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> followSystemButton.isChecked =
true
AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY -> batterySaverButton.isChecked = true
}
}
这是我尝试从跟随系统切换到暗模式时的 logcat:
2021-04-29 01:13:28.162 14075-14075/com.istemanipal.lumos D/ThemeFragment: 2
2021-04-29 01:13:28.170 14075-14075/com.istemanipal.lumos D/ThemeFragment: -1
2021-04-29 01:13:28.181 14075-14075/com.istemanipal.lumos D/ThemeFragment: 2
2021-04-29 01:13:28.188 14075-14075/com.istemanipal.lumos D/ThemeFragment: -1
2021-04-29 01:13:28.196 14075-14075/com.istemanipal.lumos D/ThemeFragment: 2
2021-04-29 01:13:28.207 14075-14075/com.istemanipal.lumos D/ThemeFragment: -1
2021-04-29 01:13:28.215 14075-14075/com.istemanipal.lumos D/ThemeFragment: 2
这是一个无限循环。作为参考,我将用户首选项存储为 AppCompatDelegate 的常量(因为这样我可以准确地调用 AppCompatDelegate setDefaultNightMode)。我正在运行在系统范围内应用暗模式的 Android 10 设备。
用于更改主题的代码:
//setup on click listeners for each radio button
binding.lightThemeButton.setOnCheckedChangeListener { _, isChecked ->
viewModel.changeTheme(AppCompatDelegate.MODE_NIGHT_NO)
}
binding.darkThemeButton.setOnCheckedChangeListener { _, isChecked ->
viewModel.changeTheme(AppCompatDelegate.MODE_NIGHT_YES)
}
binding.followSystemButton.setOnCheckedChangeListener { _, isChecked ->
viewModel.changeTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
最后 MainActivity 这样做:
userPreferencesViewModel.userPreferences.observe(this) {
AppCompatDelegate.setDefaultNightMode(it)
}