Personalizar as configurações Parte do Android Jetpack

Este documento descreve como personalizar objetos Preference na sua hierarquia.

Encontrar preferências

Para acessar uma Preference individual, por exemplo, ao consultar ou definir um valor de Preference, use PreferenceFragmentCompat.findPreference(). Esse método pesquisa toda a hierarquia em busca de uma Preference com a chave fornecida.

Por exemplo, para acessar uma EditTextPreference com uma chave de "signature", faça o seguinte:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

Recupere esse Preference usando este código:

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    val signaturePreference: EditTextPreference? = findPreference("signature")
    // Do something with this preference.
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    EditTextPreference signaturePreference = findPreference("signature");
    // Do something with this preference.
}

Controlar a visibilidade das preferências

Você pode controlar quais objetos Preference ficam visíveis para o usuário quando ele navega até uma tela de configurações. Por exemplo, se uma determinada Preference for significativa somente quando um recurso correspondente estiver ativado, convém ocultar essa Preference quando o recurso estiver desativado.

Para mostrar uma Preference somente quando uma condição for atendida, primeiro defina a visibilidade da Preference como "false" no XML, conforme mostrado no exemplo a seguir:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"
        app:isPreferenceVisible="false"/>

Em onCreatePreferences(), mostre o Preference quando a condição correspondente for atendida:

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    if(/*some feature*/) {
        val signaturePreference: EditTextPreference? = findPreference("signature")
        signaturePreference?.isVisible = true
    }
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    if(/*some feature*/) {
        EditTextPreference signaturePreference = findPreference("signature");
        if (signaturePreference != null) {
            signaturePreference.setVisible(true);
        }
    }
}

Atualizar resumos de forma dinâmica

Uma Preference que mantém dados precisa mostrar o valor atual no resumo para ajudar o usuário a entender melhor o estado atual da Preference. Por exemplo, uma EditTextPreference precisa mostrar o valor do texto salvo e uma ListPreference precisa mostrar a entrada da lista selecionada. Talvez você também tenha objetos Preference que precisem atualizar o resumo deles com base no estado interno ou externo do app, por exemplo, um Preference que exibe um número de versão. Para isso, use um SummaryProvider.

Usar um SimpleSummaryProvider

ListPreference e EditTextPreference incluem implementações simples de SummaryProvider que exibem automaticamente o valor salvo de Preference como o resumo. Se nenhum valor for salvo, a mensagem "Não definido" será exibida.

Para ativar essas implementações em XML, defina app:useSimpleSummaryProvider="true".

Como alternativa, no código, é possível usar ListPreference.SimpleSummaryProvider.getInstance() e EditTextPreference.SimpleSummaryProvider.getInstance() para acessar a instância simples de SummaryProvider e, em seguida, defini-la no Preference, conforme mostrado no exemplo a seguir:

Kotlin

listPreference.summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()

Java

listPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
editTextPreference.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());

Usar um SummaryProvider personalizado

Você pode criar seu próprio SummaryProvider e substituir provideSummary() para personalizar o resumo sempre que ele for solicitado pela Preference. Por exemplo, o EditTextPreference a seguir exibe o comprimento do valor salvo como o resumo:

Uma imagem mostrando um exemplo de EditTextPreference
Figura 1. Um exemplo de EditTextPreference.

Como exemplo, considere o seguinte EditTextPreference:

<EditTextPreference
        app:key="counting"
        app:title="Counting preference"/>

Em onCreatePreferences(), você pode criar uma nova SummaryProvider e substituir provideSummary() para retornar o resumo que será mostrado:

Kotlin

val countingPreference: EditTextPreference? = findPreference("counting")

countingPreference?.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (text.isNullOrEmpty()) {
        "Not set"
    } else {
        "Length of saved value: " + text.length
    }
}

Java

EditTextPreference countingPreference = findPreference("counting");

if (countingPreference != null) {
    countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
        @Override
        public CharSequence provideSummary(EditTextPreference preference) {
            String text = preference.getText();
            if (TextUtils.isEmpty(text) || text == null){
                return "Not set";
            }
            return "Length of saved value: " + text.length();
        }
    });
}

O resumo Preference exibe o comprimento do valor salvo ou "Não definido" quando não há um valor salvo.

Personalizar uma caixa de diálogo EditTextPreference

Em uma caixa de diálogo EditTextPreference, é possível personalizar o comportamento do campo de texto anexando um OnBindEditTextListener. Esse listener é invocado quando a caixa de diálogo é mostrada ao usuário.

Como exemplo, você pode personalizar uma caixa de diálogo para aceitar apenas números. Primeiro, crie o EditTextPreference:

<EditTextPreference
        app:key="number"
        app:title="Numbers only preference"/>

Em seguida, em onCreatePreferences(), crie um novo OnBindEditTextListener e substitua onBindEditText() para personalizar o EditText quando ele for exibido ao usuário.

Kotlin

val numberPreference: EditTextPreference? = findPreference("number")

numberPreference?.setOnBindEditTextListener { editText ->
    editText.inputType = InputType.TYPE_CLASS_NUMBER
}

Java

EditTextPreference numberPreference = findPreference("number");

if (numberPreference != null) {
    numberPreference.setOnBindEditTextListener(
            new EditTextPreference.OnBindEditTextListener() {
                @Override
                public void onBindEditText(@NonNull EditText editText) {
                    editText.setInputType(InputType.TYPE_CLASS_NUMBER);
                }
            });
}

Agora, quando a caixa de diálogo for mostrada ao usuário, o teclado será aberto no modo somente numérico, para que o usuário possa inserir apenas números no EditText.

Ações de preferência

Uma Preference pode ter uma ação específica quando tocada. Por exemplo, um Preference pode atuar como um link para uma parte separada do app. Para adicionar uma ação a uma Preference, você pode definir um Intent diretamente no Preference ou definir um OnPreferenceClickListener para uma lógica mais específica.

Definir uma intent

Você pode definir uma Intent em uma Preference para iniciar um novo Fragment, Activity ou um app separado sempre que o Preference for tocado. Isso é o mesmo que usar Context.startActivity() com um determinado Intent.

Você pode definir uma Intent em XML usando uma tag <intent>. O exemplo abaixo define um Intent que inicia uma Activity:

<Preference
        app:key="activity"
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity"/>
</Preference>

Como alternativa, você pode usar setIntent() diretamente em um Preference, desta forma:

Kotlin

val intent = Intent(context, ExampleActivity::class.java)
activityPreference.setIntent(intent)

Java

Intent intent = new Intent(getContext(), ExampleActivity.class);
activityPreference.setIntent(intent);

Você também pode incluir extras com um Intent usando XML:

<Preference
        app:key="activity"
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity">
        <extra
                android:name="example_key"
                android:value="example_value"/>
    </intent>
</Preference>

Veja um exemplo de uma Preference com uma Intent que inicia uma página da Web:

<Preference
        app:key="webpage"
        app:title="View webpage">
    <intent
            android:action="android.intent.action.VIEW"
            android:data="http://www.google.com" />
</Preference>

Kotlin

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("http://www.google.com")

val webpagePreference = findPreference("webpage")
webpagePreference?.intent = intent

Java

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
webpagePreference.setIntent(intent);

OnPreferenceClickListener

Você pode definir um OnPreferenceClickListener em uma Preference, que adiciona um callback a onPreferenceClick() quando a Preference é tocada. Por exemplo, você poderá usar o listener para navegar até outro Fragment ou Activity se tiver uma lógica mais complexa para processar a navegação.

Para definir um OnPreferenceClickListener, use um código semelhante ao seguinte:

Kotlin

onClickPreference.setOnPreferenceClickListener({
    // Do something.
    true
})

Java

onClickPreference.setOnPreferenceClickListener(preference -> {
    // Do something.
    return true;
});