https://kotlinlang.org logo
Title
f

Florian

08/28/2021, 7:36 PM
Is this the correct approach to programmatically switch dark/light theme from a user setting? I just recompose the whole activity (which contains all screens of the app)
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedTheme by appPreferencesViewModel.selectedTheme.collectAsState(null)

            selectedTheme?.let { selectedTheme ->
                val darkTheme = when (selectedTheme) {
                    ThemeSelectionValues.LIGHT -> false
                    ThemeSelectionValues.DARK -> true
                    ThemeSelectionValues.SYSTEM -> isSystemInDarkTheme()
                }
                MyAppTheme(darkTheme = darkTheme) {
                    // ActivityBody with NavHost
                }
            }
        }
    }
}
a

adjpd

08/28/2021, 11:25 PM
If you've set
ThemeSelectionValues.SYSTEM
and you change the system's dark/light mode, I guess it changes correctly? Looks okay to me. That's what I want to do in my next release anyhow.
Unsolicited code clean up since I'm bored...
val darkTheme = selectedTheme?.let {
  when (it) {
   ThemeSelectionValues.LIGHT -> false
   ThemeSelectionValues.DARK -> true
   ThemeSelectionValues.SYSTEM -> isSystemInDarkTheme()
  }
} 
MyAppTheme(darkTheme = darkTheme) { 
  //ActivityBody with NavHost
}
f

Florian

08/29/2021, 8:50 AM
@adjpd Thank you 👍 Yes it works correctly, I just wasn't sure if recomposing the whole screen was the way to go
@adjpd actually,
MyAppTheme
has to be inside the
?.let
because we need it to be not nullable
a

Albert Chang

08/29/2021, 10:47 AM
Consider make
appPreferencesViewModel.selectedTheme
a
StateFlow
so that you get the correct value immediately. Now if the user chose dark theme and the system is in light theme, when you app starts, it will render light theme at first, and then render dark theme immediately after that, which is a waste.
f

Florian

08/29/2021, 2:05 PM
@Albert Chang We can't get the theme immediately because DataStore loads the preference asynchronously. Right now I'm not showing the layout at all until the value is loaded (that's why
MyAppTheme
is inside the
?.let
block.