Sobes.tech
Middle

How to save and apply theme settings in an Android application?

sobes.tech AI

Answer from AI

There are several approaches to save and apply theme settings in an Android application.

  1. SharedPreferences: A simple way to save small amounts of data, such as the identifier of the selected theme.

    // Saving theme
    val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return
    with (sharedPref.edit()) {
        putInt(getString(R.string.saved_theme_key), themeId)
        apply()
    }
    
    // Reading theme
    val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE)
    val defaultValue = resources.getInteger(R.integer.default_theme_id)
    val savedThemeId = sharedPref?.getInt(getString(R.string.saved_theme_key), defaultValue) ?: defaultValue
    
    // Applying theme in Activity
    setTheme(savedThemeId)
    super.onCreate(savedInstanceState)
    
  2. DataStore: A more modern and asynchronous way to save data, offering data streams and more reliable storage.

    // DataStore
    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
    
    // Saving theme
    suspend fun saveTheme(themeId: Int) {
        dataStore.edit { settings ->
            settings[intPreferencesKey("theme_id")] = themeId
        }
    }
    
    // Getting theme
    val themeFlow: Flow<Int> = dataStore.data
        .catch { exception ->
            if (exception is IOException) {
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }
        .map { preferences ->
            preferences[intPreferencesKey("theme_id")] ?: R.style.Theme_App
        }
    

    Applying the theme in an Activity can happen after retrieving the value from DataStore (for example, using collect in a coroutine) and calling setTheme. Recreating the Activity might be necessary after changing the theme for proper display.

  3. System theme settings: Android also provides built-in support for themes: light, dark, and default (follows system settings). This can be implemented through resources.

    • Creating styles for light and dark themes (e.g., res/values/themes.xml and res/values-night/themes.xml).
    • Setting AppCompatDelegate.setDefaultNightMode to apply the theme programmatically or configuring it in the activity's manifest via android:theme.

Applying a theme often requires recreating the Activity to ensure resources are loaded correctly. You can use recreate() for this purpose.