Sobes.tech
Junior

Jak zapisać i używać ustawień motywu w aplikacji na Androida?

sobes.tech AI

Odpowiedź od AI

Skuteczne podejście obejmuje użycie SharedPreferences do zapisywania wybranego motywu i AppCompatDelegate.setDefaultNightMode() do jego zastosowania.

  1. Zapisz motyw: Użyj SharedPreferences, aby przechować identyfikator wybranego motywu (np. "light", "dark", "system").

    // Uzyskaj SharedPreferences
    val sharedPrefs = getSharedPreferences("AppTheme", Context.MODE_PRIVATE)
    // Uzyskaj edytor
    val editor = sharedPrefs.edit()
    // Zastosuj motyw z ID themeId
    editor.putString("current_theme", themeId)
    // Zapisz zmiany
    editor.apply()
    
  2. Zastosuj motyw przy starcie: W głównej Activity lub klasie Application odczytaj zapisane wartości z SharedPreferences i zastosuj motyw.

    // Odczytaj zapisany motyw
    val themeId = getSharedPreferences("AppTheme", Context.MODE_PRIVATE)
        .getString("current_theme", "system") // Domyślnie 'system'
    
    // Zastosuj motyw
    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)
    }
    
  3. Zmiana motywu przez użytkownika: Udostępnij interfejs użytkownika (np. RadioButton w ustawieniach), gdzie użytkownik może wybrać motyw. Po wyborze zapisz nowy identyfikator w SharedPreferences i natychmiast zastosuj motyw, wywołując AppCompatDelegate.setDefaultNightMode() i w razie potrzeby restartując Activity, aby poprawnie zastosować motyw.

    // Załóżmy, że użytkownik wybrał motyw ciemny
    val sharedPrefs = getSharedPreferences("AppTheme", Context.MODE_PRIVATE)
    val editor = sharedPrefs.edit()
    editor.putString("current_theme", "dark")
    editor.apply()
    
    // Zastosuj motyw natychmiast
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
    
    // Lub użyj recreate() do pełnego zastosowania motywu
    // recreate()
    

Ponowne uruchomienie Activity za pomocą recreate() może być konieczne, aby wszystkie widoki w bieżącej Activity zostały poprawnie narysowane z nowym motywem.

  1. Definiowanie motywów w styles.xml: Zdefiniuj style dla jasnego i ciemnego motywu w res/values/styles.xml i res/values-night/styles.xml odpowiednio, dziedzicząc od tematów Theme.AppCompat.

    <!-- res/values/styles.xml -->
    <style name="AppTheme.Light" parent="Theme.AppCompat.Light">
        <!-- Definicje stylów dla jasnego motywu -->
    </style>
    
    <!-- res/values-night/styles.xml -->
    <style name="AppTheme.Dark" parent="Theme.AppCompat">
        <!-- Definicje stylów dla ciemnego motywu -->
    </style>
    

W AndroidManifest.xml określ bazowy motyw aplikacji:

```xml
<!-- AndroidManifest.xml -->
<application
    android:theme="@style/AppTheme.Light"
    ...>
    <!-- ... Activities -->
</application>
```
  1. Monitorowanie zmian motywu: W przypadku zmiany systemu (np. według harmonogramu lub ręcznie przez użytkownika w ustawieniach telefonu), można użyć Configuration.uiMode w onConfigurationChanged(), aby na to zareagować, ale AppCompatDelegate zwykle obsługuje to automatycznie przy użyciu MODE_NIGHT_FOLLOW_SYSTEM.

    @Override
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        // Możesz sprawdzić nowy motyw, jeśli to konieczne
        // val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
        // ...
    }
    

Użycie AppCompatDelegate jest zalecanym podejściem do obsługi motywów na Androidzie, ponieważ zapewnia kompatybilność wsteczną i poprawne działanie z różnymi komponentami biblioteki wsparcia.