How to save and use theme settings in an Android application?
sobes.tech AI
Answer from AI
An effective approach involves using SharedPreferences to save the selected theme and AppCompatDelegate.setDefaultNightMode() to apply it.
-
Saving the theme: Use
SharedPreferencesto store the identifier of the chosen theme (e.g., "light", "dark", "system").// Get SharedPreferences val sharedPrefs = getSharedPreferences("AppTheme", Context.MODE_PRIVATE) // Get editor val editor = sharedPrefs.edit() // Apply theme with ID themeId editor.putString("current_theme", themeId) // Save changes editor.apply() -
Applying the theme at startup: In the main
ActivityorApplicationclass, read the saved value fromSharedPreferencesand apply the theme.// Read the saved theme value val themeId = getSharedPreferences("AppTheme", Context.MODE_PRIVATE) .getString("current_theme", "system") // default to 'system' // Apply the theme when (themeId) { "light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) "dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) "system" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) } -
Changing the theme by the user: Provide a user interface (e.g.,
RadioButtonin settings) where the user can select a theme. When selected, save the new identifier inSharedPreferencesand immediately apply the theme by callingAppCompatDelegate.setDefaultNightMode()and, if necessary, restart theActivityfor proper theme application.// Suppose the user selected a dark theme val sharedPrefs = getSharedPreferences("AppTheme", Context.MODE_PRIVATE) val editor = sharedPrefs.edit() editor.putString("current_theme", "dark") editor.apply() // Apply the theme immediately AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) // Or recreate() for full theme application // recreate()Restarting the
Activitywithrecreate()may be necessary to ensure all Views in the currentActivityare correctly redrawn with the new theme. -
Defining themes in
styles.xml: Define styles for light and dark themes inres/values/styles.xmlandres/values-night/styles.xml, inheriting fromTheme.AppCompat.<!-- res/values/styles.xml --> <style name="AppTheme.Light" parent="Theme.AppCompat.Light"> <!-- Style definitions for light theme --> </style> <!-- res/values-night/styles.xml --> <style name="AppTheme.Dark" parent="Theme.AppCompat"> <!-- Style definitions for dark theme --> </style>In
AndroidManifest.xml, specify the base theme of the application:<!-- AndroidManifest.xml --> <application android:theme="@style/AppTheme.Light" ...> <!-- ... Activities --> </application> -
Listening for theme changes: In case the system theme changes (e.g., on schedule or manually via phone settings), you can use
Configuration.uiModeinonConfigurationChanged()to respond, butAppCompatDelegateusually handles this automatically when usingMODE_NIGHT_FOLLOW_SYSTEM.@Override override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) // You can check the new theme if needed // val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK // ... }
Using AppCompatDelegate is the recommended approach for theme support on Android, as it provides backward compatibility and proper working with various support library components.