Sobes.tech
Junior

Como guardar e usar as configurações do tema numa aplicação Android?

sobes.tech IA

Resposta da IA

Uma abordagem eficaz inclui o uso de SharedPreferences para guardar o tema selecionado e AppCompatDelegate.setDefaultNightMode() para aplicá-lo.

  1. Guardar o tema: Utilize SharedPreferences para armazenar o identificador do tema selecionado (por exemplo, "light", "dark", "system").

    // Obter SharedPreferences
    val sharedPrefs = getSharedPreferences("AppTheme", Context.MODE_PRIVATE)
    // Obter o editor
    val editor = sharedPrefs.edit()
    // Aplicar o tema com ID themeId
    editor.putString("current_theme", themeId)
    // Guardar alterações
    editor.apply()
    
  2. Aplicar o tema ao iniciar: Na Activity principal ou na classe Application, leia o valor guardado em SharedPreferences e aplique o tema.

    // Ler o valor guardado do tema
    val themeId = getSharedPreferences("AppTheme", Context.MODE_PRIVATE)
        .getString("current_theme", "system") // Por padrão 'system'
    
    // Aplicar o tema
    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. Alteração de tema pelo utilizador: Forneça uma interface de utilizador (por exemplo, RadioButton nas configurações), onde o utilizador possa escolher um tema. Ao selecionar, guarde o novo identificador em SharedPreferences e aplique imediatamente o tema chamando AppCompatDelegate.setDefaultNightMode(), e se necessário, reinicie a Activity para aplicar corretamente o tema.

    // Suponha que o utilizador escolheu tema escuro
    val sharedPrefs = getSharedPreferences("AppTheme", Context.MODE_PRIVATE)
    val editor = sharedPrefs.edit()
    editor.putString("current_theme", "dark")
    editor.apply()
    
    // Aplicar o tema imediatamente
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
    
    // Ou usar recreate() para aplicar completamente o tema
    // recreate()
    

Reiniciar a Activity com recreate() pode ser necessário para que todas as vistas na Activity atual sejam redesenhadas corretamente com o novo tema.

  1. Definição de temas em styles.xml: Defina estilos para os temas claro e escuro em res/values/styles.xml e res/values-night/styles.xml respetivamente, herdando dos temas Theme.AppCompat.

    <!-- res/values/styles.xml -->
    <style name="AppTheme.Light" parent="Theme.AppCompat.Light">
        <!-- Definições de estilos para tema claro -->
    </style>
    
    <!-- res/values-night/styles.xml -->
    <style name="AppTheme.Dark" parent="Theme.AppCompat">
        <!-- Definições de estilos para tema escuro -->
    </style>
    

No AndroidManifest.xml, indique o tema base da aplicação:

```xml
<!-- AndroidManifest.xml -->
<application
    android:theme="@style/AppTheme.Light"
    ...>
    <!-- ... Activities -->
</application>
```
  1. Monitorização de alterações de tema: No caso de alterações do sistema (por exemplo, por horário ou manualmente pelo utilizador através das configurações do telefone), pode usar Configuration.uiMode em onConfigurationChanged() para reagir, mas AppCompatDelegate normalmente trata isso automaticamente ao usar MODE_NIGHT_FOLLOW_SYSTEM.

    @Override
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        // Pode verificar o novo tema, se necessário
        // val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
        // ...
    }
    

O uso de AppCompatDelegate é a abordagem recomendada para suportar temas no Android, pois garante compatibilidade retroativa e funcionamento correto com diferentes componentes da biblioteca de suporte.