I have been working on a pet project where I initially used SharedPreferences
to persist settings Preference
objects. I decided to migrate it to use data store
instead of SharedPreferences
.
So I started with the ListPreference
for the dark theme configuration. It worked fine as expected but the ListPreference
keep reverting to its default value (system_default_theme
) whenever the theme configuration changes.
For instance, when I select dark_theme
from the ListPreference
dialog, the app switches to dark theme and the activity is destroyed as well as the preference fragment. Whenever the fragment is recreated, the ListPreference
displays the default value which is system_default_theme
instead of dark_theme
.
The app remains in dark_theme
while the ListPreference
shows system_default_theme
as selected. More like the selection is lost or reverted on configuration change or when the fragment is destroyed. It seems the selection in the UI no longer reflects the stored preference value.
My last resort right now is to just get rid of the XML
and just use Jetpack Compose
instead.
I used Proto DataStore
.
The ListPreference
in settings.xml:
<ListPreference
android:entries="@array/entries_theme"
android:icon="@drawable/device_theme"
android:key="key_dark_mode"
android:summary="Turn on/off dark mode."
android:title="Dark mode"
app:defaultValue="system_default"
app:entryValues="@array/entry_value_theme"
app:useSimpleSummaryProvider="true" />
Here's the implementation of the custom data store
in the onCreatePreferences()
of SettingsPreferenceFragment.kt :
findPreference<ListPreference>("key_dark_mode")
?.apply {
preferenceDataStore = object : PreferenceDataStore() {
override fun putString(key: String?, value: String?) {
val darkThemeConfig =
value?.getDarkThemeConfig() ?: DarkThemeConfig.FOLLOW_SYSTEM
settingsViewModel.updateDarkThemeConfig(darkThemeConfig)
}
override fun getString(key: String?,defValue: String?): String? {
return settingsUiState.settings.darkThemeConfig.getDarkMode()
}
}
}
Theme entries and values string arrays
:
<!-- theme entries array -->
<string-array name="entries_theme">
<item>Light mode</item>
<item>Dark mode</item>
<item>Use device settings</item>
</string-array>
<!-- theme entry values array -->
<string-array name="entry_value_theme">
<item>light_mode</item>
<item>dark_mode</item>
<item>system_default</item>
</string-array>
Thanks in advance for your helpful answers. :)