Issue
I have switched my App from using SharedPreferences to PreferencesDataStore. I have also implemented a dark mode and several themes inside my App. For theming, I basically rely in each activity on this code:
val themePreferences = getSharedPreferences("THEME_PREFERENCES", MODE_PRIVATE)
val settingsPreferences = getSharedPreferences("SETTINGS_PREFERENCES", MODE_PRIVATE)
darkMode = settingsPreferences.getBoolean("darkMode", false)
setTheme(when (darkMode) {
true -> themePreferences.getInt("themeDark", R.style.AppThemeDark)
false -> themePreferences.getInt("themeLight", R.style.AppThemeLight)
})
The selected theme gets stored as an Integer, each once for the light mode as well as the dark mode. Now, I also want to adopt this section of my code. I get my darkMode boolean from my dataStore repository like this:
viewModel.storedDarkMode.observe(this) { darkMode = it }
If I work inside the observe(this) { ... } of the LiveData object it won't work. Now, how can I change my code snippet shown above to PreferencesDataStore? Or is it actually better e.g. to make a seperate class in order to observe the values from there? If yes, how could something like that look like? Or do you know some good example code following Android Architecture including custom themes with a dark mode where I can look at?
I am still learning alot, any help for better understanding this is much appreaciated!
Best regards, Markus
Edit:
runBlocking {
val darkMode = viewModel.darkModeFlow.first()
setTheme(when (darkMode) {
true -> viewModel.themeDarkFlow.first()
false -> viewModel.themeLightFlow.first()
})
}
Solution
I don't know if it is best practice or not, but I use runBlocking
to get theme data from dataStore
. It is always recommended that, we should never use runBlocking
in our production code.
val preferences = runBlocking {
mainActivityViewModel.preferencesFlow.first()
}
setAppTheme(preferences.currentTheme)
binding = ActivityMainBinding.inflate(layoutInflater)
In setAppTheme
method
private fun setAppTheme(theme: Boolean) {
mainActivityViewModel.darkMode = theme
//set your theme here
}
Now observe preferencesFlow
for any change in theme value, and if the theme is changed then recreate()
mainActivityViewModel.preferencesLiveData.observe(this) {
if (it.currentTheme != mainActivityViewModel.selectedTheme) {
recreate()
}
}
As we can't load our UI, without getting the theme. It seemed right to use runBlocking
.
Answered By - Praveen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.