Eliminar/ocultar una preferencia de la pantalla

5 minutos de lectura

avatar de usuario
Alex Volovoy

Tengo una actividad que extiende PreferenceActivity. Estoy cargando preferencias desde el archivo xml. Pero en algunos casos necesito ocultar por completo una de las preferencias de la pantalla según el estado de mi aplicación. Hay un método setEnabled, pero no es exactamente lo que quiero. Quiero eliminar esa preferencia de la pantalla por completo. Es posible ?

avatar de usuario
Kavi

Si tu Preference está dentro de un PreferenceCategoryTienes que hacer esto:

XML:

<PreferenceCategory
    android:key="category_foo"
    android:title="foo">

    <CheckBoxPreference
        android:key="checkPref" />

Java:

CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
mCategory.removePreference(mCheckBoxPref);

  • Para ser justos, la respuesta anterior dice que necesita al padre PreferenceCategory.

    – mate

    6 de junio de 2014 a las 0:09

avatar de usuario
David Hedlund

Sí, si tiene una referencia tanto para el Preferencey su padre (un PreferenceCategoryo PreferenceScreen)

myPreferenceScreen.removePreference(myPreference);

  • ¿Podría haber respondido mi propia pregunta a través de esto? stackoverflow.com/a/4704360/956975

    – Marienke

    23 de febrero de 2017 a las 11:58

  • Desafortunadamente, elimina permanentemente la preferencia. ¿Es posible simplemente ocultarlo?

    – Dmitri

    23/09/2018 a las 21:09

  • A mi tampoco me funciona. ¡La preferencia se mantiene!

    – Dmitri

    23/09/2018 a las 21:12

  • @Dmitry Puedes simplemente atenuarlo con setEnabled()

    – JakeD

    9 de junio de 2020 a las 17:12

  • @Dmitry Tienes que llamar removePreference en el padre directo, que puede obtener con getParent() (ver esta respuesta).

    – usuario905686

    15 oct 2020 a las 14:27

En el caso de que la Preferencia sea un elemento secundario directo de la pantalla de preferencias, aquí hay un código independiente:

PreferenceScreen screen = getPreferenceScreen();
Preference pref = getPreferenceManager().findPreference("mypreference");
screen.removePreference(pref);

  • Esto no funcionará si la preferencia se encuentra dentro de la categoría. tienes que findPreference para la categoría y eliminar la preferencia de la categoría

    – MBH

    10 de septiembre de 2017 a las 14:34

  • @MBH: ¡Gracias por mencionar esa advertencia!

    – 1”

    11 de septiembre de 2017 a las 3:49

Si estás usando PreferenceFragmentCompatPreferenceFragmentCompat puede configurar la visibilidad en xml.

Las preferencias en su xml se convertirán a versiones de AppCompat automáticamente. A continuación, puede utilizar el ‘aplicación: isPreferenceVisible‘ atributo en su xml

preferencias.xml

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

    <CheckBoxPreference
        android:defaultValue="false"
        android:key="show.navigation"
        android:title="Show navigation"
        app:isPreferenceVisible="false" />

...

El atributo está documentado en https://developer.android.com/guide/topics/ui/settings/components-and-attributes

agregando PreferenceFragmentCompat está documentado en https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy

Ejemplo:

public class MySettingsActivity extends AppCompatActivity {

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

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

Si desea algo que cambie dinámicamente las preferencias, por ejemplo, en un SwitchPreference, he encontrado que la mejor manera es poner todas mis subopciones en contenedores de dos categorías. Inicialmente, tendrá todo lo que se muestra, luego simplemente elimine las partes que no desea. La parte inteligente es que solo activa la recreación cuando algo cambia y luego no tiene que crear nada manualmente ni preocuparse por volver a colocar las cosas en el orden correcto.

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  addPreferencesFromResource(R.xml.preferences);
  PreferenceCategory prefCatOne= (PreferenceCategory)findPreference("prefCatOne");
  PreferenceCategory prefCatTwo= (PreferenceCategory)findPreference("prefCatTwo");
  SwitchPreference mySwitchPref= (SwitchPreference)findPreference("mySwitchPref");
  PreferenceScreen screen = getPreferenceScreen();
  if (mySwitchPref.isChecked()) {
    screen.removePreference(prefCatOne);
  } else {
    screen.removePreference(prefCatTwo);
  }
}

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    if (key.equals("mySwitchPref")) {
        this.recreate();
    }
}

El único inconveniente que puedo ver con esto es que hay un flash ya que la pantalla se recrea desde cero.

  • El caso no funciona, al menos no en 22. Pero cambiarlo a Preferencia (aunque sea una agrupación de preferencias) sí funciona.

    – robo

    02/04/2015 a las 16:21

  • Rob, acabo de probar el código anterior en un API22 AVD y funciona bien. Asegúrese de que el contenido XML de su preferencia coincida con su código. Para el ejemplo anterior, SwitchPreference puede estar en cualquier lugar, pero necesita PreferenceCategorys para ser elementos secundarios directos de PreferenceScreen.

    – Jaime

    02/04/2015 a las 20:46

  • Acabo de obtener la categoría como preferencia, sin molde, y la eliminé. Trabajó.

    – robo

    3 de abril de 2015 a las 1:14


avatar de usuario
JJD

En su archivo XML:

<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:key="preferenceScreen">

    <PreferenceCategory
        android:key="personalisation"
        android:title="your title here">

        <ThemedPreference
            android:key="animation" />

</PreferenceScreen>

En tu código:

PreferenceScreen pPreferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");

PreferenceCategory pCategory = (PreferenceCategory) findPreference("personalisation");
ThemedPreference pThemePref = (ThemedPreference) findPreference("animation");

pPreferenceScreen.removePreference(pCategory); //remove category
pCategory.removePreference(pThemePref);   // remove preference

  • El caso no funciona, al menos no en 22. Pero cambiarlo a Preferencia (aunque sea una agrupación de preferencias) sí funciona.

    – robo

    02/04/2015 a las 16:21

  • Rob, acabo de probar el código anterior en un API22 AVD y funciona bien. Asegúrese de que el contenido XML de su preferencia coincida con su código. Para el ejemplo anterior, SwitchPreference puede estar en cualquier lugar, pero necesita PreferenceCategorys para ser elementos secundarios directos de PreferenceScreen.

    – Jaime

    02/04/2015 a las 20:46

  • Acabo de obtener la categoría como preferencia, sin molde, y la eliminé. Trabajó.

    – robo

    3 de abril de 2015 a las 1:14


avatar de usuario
JJD

Recomiendo usar la preferencia v7, tiene setVisible() método. Pero aún no lo he probado. En consecuencia tienes que usar PreferenceFragment en vez de PreferenceActivity.

  • La respuesta aceptada no funcionará para V7. Usar setVisible funciona para V7

    – m12lrpv

    22 de octubre de 2018 a las 8:15


  • V7 también tiene getParent()por lo que puede eliminar la preferencia como se describe en esta respuesta.

    – usuario905686

    15 oct 2020 a las 14:25

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad