Cómo personalizar la configuración   Parte de Android Jetpack.

En este tema, se describe cómo personalizar Preferences en la jerarquía.

Cómo buscar objetos Preference

Para acceder a un objeto Preference individual, como cuando recibes o configuras un valor Preference, usa PreferenceFragmentCompat.findPreference(). Este método busca en toda la jerarquía un objeto Preference con la clave determinada.

A modo de ejemplo, a partir de un objeto EditTextPreference con una clave "signature":

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

Podemos recuperar este objeto Preference si usamos el siguiente 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
}

Cómo controlar la visibilidad de objetos Preference

Puedes controlar los objetos Preferences que se muestran al usuario cuando navega a una pantalla de configuración. Por ejemplo, si un objeto Preference en particular es significativo solo cuando se habilita una función correspondiente, es posible que quieras ocultar ese objeto Preference cuando la función está inhabilitada.

Para mostrar un objeto Preference solo cuando se cumple una condición, establece primero la visibilidad del objeto Preference como "false" en el XML, tal como se muestra en el siguiente ejemplo:

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

Luego, en onCreatePreferences(), muestra el objeto Preference cuando se cumple la condición correspondiente:

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);
        }
    }
}

Cómo actualizar resúmenes de manera dinámica

Un objeto Preference con datos persistentes debe mostrar el valor actual en su parámetro summary como ayuda al usuario para comprender mejor el estado actual del objeto Preference. Por ejemplo, un objeto EditTextPreference debería mostrar el valor de texto guardado actualmente y un objeto ListPreference debería mostrar la entrada de la lista seleccionada actualmente. También es posible que tengas un objeto Preferences que debe actualizar su resumen sobre la base del estado interno o externo de la app: por ejemplo, un objeto Preference que muestra un número de versión. Esto puede hacerse con un objeto SummaryProvider.

Cómo usar un objeto SimpleSummaryProvider

ListPreference y EditTextPreference incluyen implementaciones de SummaryProvider simples que muestran automáticamente el valor de Preference guardado como resumen. En caso de no haberse guardado un valor, muestran "Not set".

Puedes habilitar esas implementaciones desde XML si configuras app:useSimpleSummaryProvider="true".

Como opción, en el código, puedes usar ListPreference.SimpleSummaryProvider.getInstance() y EditTextPreference.SimpleSummaryProvider.getInstance() para obtener la instancia de SummaryProvider simple y, luego, configurarla en el objeto Preference, tal como se muestra en el siguiente ejemplo:

Kotlin

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

Java

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

Cómo usar un objeto SummaryProvider personalizado

Puedes crear tu propio objeto SummaryProvider y anular el objeto provideSummary() para personalizar el resumen siempre que lo solicite el objeto Preference. Por ejemplo, el objeto EditTextPreference que se incluye a continuación muestra la longitud de su valor guardado como resumen:

A modo de ejemplo, supongamos lo siguiente EditTextPreference:

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

En onCreatePreferences(), crea un nuevo objeto SummaryProvider y anula provideSummary() para mostrar el resumen que se incluirá.

Kotlin

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

countingPreference?.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (TextUtils.isEmpty(text)) {
        "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)){
                return "Not set";
            }
            return "Length of saved value: " + text.length();
        }
    });
}

El resumen de objetos Preference ahora muestra la longitud del valor guardado o "Not set" cuando no existe un valor guardado.

Cómo personalizar un diálogo EditTextPreference

En un diálogo EditTextPreference, puedes personalizar el comportamiento del campo de texto si adjuntas un objeto OnBindEditTextListener. Este objeto de escucha se invoca cuando se muestra el diálogo al usuario.

A modo de ejemplo, puedes personalizar un diálogo para que solo acepte números. Primero, crea el objeto EditTextPreference:

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

A continuación, en onCreatePreferences(), crea un nuevo objeto OnBindEditTextListener y anula onBindEditText() para personalizar el objeto EditText cuando se muestra al usuario.

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);
                }
            });
}

Ahora, cuando el usuario ve el diálogo, se abre el teclado en el modo numérico para que únicamente pueda ingresar números en el objeto EditText.

Acciones de Preference

Un objeto Preference puede ejercer una acción específica cuando se lo presiona. Por ejemplo, un objeto Preference puede actuar como vínculo a una parte separada de tu aplicación. Para agregar una acción a un objeto Preference, puedes configurar un elemento Intent en el objeto Preference directamente o puedes configurar un elemento OnPreferenceClickListener para una lógica más específica.

Cómo configurar un elemento Intent

Puedes configurar un elemento Intent en un objeto Preference para que inicie un nuevo Fragment, Activity o una aplicación diferente siempre que se presione el objeto Preference. Esto sería similar a usar Context.startActivity() con un elemento Intent determinado.

Puedes configurar un elemento Intent en el archivo XML si usas una etiqueta <intent> anidada. El ejemplo que se incluye a continuación define un elemento Intent que inicia un objeto Activity:

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

Como opción, puedes usar setIntent() directamente en un objeto Preference, tal como se muestra a continuación:

Kotlin

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

Java

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

También puedes incluir servicios adicionales con un elemento Intent a través de 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>

Aquí se muestra un ejemplo de un objeto Preference con un elemento Intent que abre una página 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")
webpagePreference.setIntent(intent)

Java

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

OnPreferenceClickListener

Puedes configurar un objeto OnPreferenceClickListener en un objeto Preference, que agrega una devolución de llamada a onPreferenceClick() cuando se presiona Preference. Por ejemplo, puedes usar el objeto de escucha para desplazarte a otro objeto Fragment o Activity si tiene una lógica más compleja para procesar la navegación.

Para configurar un objeto OnPreferenceClickListener, usa código similar al siguiente:

Kotlin

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

Java

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