Setup theme for dark mode in Android

373 Views Asked by At

I designed a theme settings fragment to let user choose between themes . It writes values to a Preferences Datastore which this then observed by the ViewModel's observer and theme is changed accordingly. However when I try to switch from System default to Dark mode, the observer goes in a loop. This is how my code for the observer looks like:

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
                }
            }

This is the logcat when I try to switch from Follow System to Dark mode:

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

This goes in an infinite loop. For reference I am storing User Preferences as AppCompatDelegate's constants(cause that way I can just call AppCompatDelegate setDefaultNightMode exactly). I am running an Android 10 Device with the Dark Mode applied system wide.

Code used for changing the theme:

//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)
        }

Finally the MainActivity does this:

userPreferencesViewModel.userPreferences.observe(this) {
            AppCompatDelegate.setDefaultNightMode(it)
        }
0

There are 0 best solutions below