0

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. :)

0 Answers0