Configurações   Parte do Android Jetpack.

As configurações permitem que os usuários mudem a funcionalidade e o comportamento de um app. Elas podem afetar o comportamento em segundo plano, como a frequência com que o app sincroniza dados com a nuvem, ou podem ter um alcance maior, como alterar o conteúdo e a apresentação da interface do usuário.

Para integrar as configurações ajustáveis do usuário no seu app, use a biblioteca AndroidX Preference. Essa biblioteca gerencia a interface do usuário e interage com o armazenamento para que você defina apenas as configurações individuais que o usuário pode definir. Ela vem com um tema do Material Design que oferece uma experiência do usuário consistente em todos os dispositivos e versões do SO.

Primeiros passos

Um Preference é o elemento básico da biblioteca Preference. Uma tela de configurações contém uma hierarquia Preference. É possível definir essa hierarquia como um recurso XML ou criar uma hierarquia no código.

As seções a seguir descrevem como criar uma tela de configurações simples usando a biblioteca AndroidX Preference.

Antes de começar, adicione a dependência da biblioteca Preference ao arquivo build.gradle:

Groovy

dependencies {
    implementation "androidx.preference:preference-ktx:1.2.0"
}

Kotlin

dependencies {
    implementation("androidx.preference:preference-ktx:1.2.0")
}

Após uma sincronização do Gradle, você pode passar para a parte XML da tarefa.

Criar uma hierarquia

No projeto, navegue até a pasta res/xml, crie um arquivo preferences.xml e adicione o seguinte código:

<PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

    <Preference
        app:key="feedback"
        app:title="Send feedback"
        app:summary="Report technical issues or suggest new features"/>

</PreferenceScreen>

Essa hierarquia contém dois objetos Preference: um SwitchPreferenceCompat que permite aos usuários ativar e desativar uma configuração e um Preference básico sem widget.

Ao criar uma hierarquia, cada Preference precisa ter uma chave exclusiva.

Inflar a hierarquia

Para inflar uma hierarquia a partir de um atributo XML, crie um PreferenceFragmentCompat, modifique onCreatePreferences() e forneça o recurso XML que será inflado, conforme mostrado no exemplo a seguir:

Kotlin

class MySettingsFragment : PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)
    }
}

Java

public class MySettingsFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.preferences, rootKey);
    }
}

Em seguida, você poderá adicionar esse Fragment à Activity, como em qualquer Fragment:

Kotlin

class MySettingsActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings_container, MySettingsFragment())
                .commit()
    }
}

Java

public class MySettingsActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings_container, new MySettingsFragment())
                .commit();
    }
}

O resultado é mostrado na imagem abaixo:

Uma imagem mostrando um exemplo de tela de preferências
Figura 1. Uma tela de configurações criada usando dois objetos Preference.

Monitorar as preferências

Você pode receber um evento quando uma preferência muda registrando um listener para ela:

Kotlin

findPreference<SwitchPreferenceCompat>("notifications")
    ?.setOnPreferenceChangeListener { _, newValue ->
        Log.d("Preferences", "Notifications enabled: $newValue")
        true // Return true if the event is handled.
    }

findPreference<Preference>("feedback")
    ?.setOnPreferenceClickListener {
        Log.d("Preferences", "Feedback was clicked")
        true // Return true if the click is handled.
    }

Java

SwitchPreferenceCompat notificationsPref = findPreference("notifications");

if (notificationsPref != null) {
    notificationsPref.setOnPreferenceChangeListener((preference, newValue) -> {
        Log.d("Preferences", String.format("Notifications enabled: %s", newValue));
        return true; // Return true if the event is handled.
    });
}

Preference feedbackPref = findPreference("feedback");

if (feedbackPref != null) {
    feedbackPref.setOnPreferenceClickListener((preference) -> {
        Log.d("Preferences", "Feedback was clicked");
        return true; // Return true if the event is handled.
    });
}

Ler o valor atual da preferência

PreferenceFragmentCompat oculta grande parte da maquinaria envolvida no salvamento e na leitura das preferências. No entanto, tudo é armazenado usando SharedPreferences, e você pode ler esses valores como faria normalmente com SharedPreferences:

Kotlin

val preferences = PreferenceManager.getDefaultSharedPreferences(this).all

preferences.forEach {
    Log.d("Preferences", "${it.key} -> ${it.value}")
}

Java

var preferences = PreferenceManager.getDefaultSharedPreferences(context).getAll();

preferences.forEach((key, value) ->{
    Log.d("Preferences", String.format("%s -> %s", key, value));
});

O snippet anterior recebe uma instância do SharedPreferences padrão para o app, acessa todos os valores armazenados, faz um loop sobre eles e os exibe no Logcat.