Supprimer / masquer une préférence de l'écran


134

J'ai une activité qui étend PreferenceActivity. Je charge les préférences à partir du fichier xml. Mais dans certains cas, je dois masquer complètement l'une des préférences de l'écran en fonction de l'état de mon application. Il existe une méthode setEnabled, mais ce n'est pas exactement ce que je veux. Je souhaite supprimer complètement cette préférence de l'écran. C'est possible ?

Réponses:


171

Oui, si vous avez une référence à la fois au Preference, et à son parent (a PreferenceCategory, ou PreferenceScreen)

myPreferenceScreen.removePreference(myPreference);

Génial! Merci! Fonctionne et prend tout son sens
Bostone

J'aurais pu répondre à ma propre question à travers cela? stackoverflow.com/a/4704360/956975
marienke

2
Malheureusement, cela supprime définitivement la préférence. Est-il possible de le cacher?
Dmitry

Cela ne fonctionne pas non plus pour moi. La préférence demeure!
Dmitry

@Dmitry Vous pouvez simplement le setEnabled()
griser

212

Si vous êtes Preferencedans un PreferenceCategory, vous devez faire ceci:

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

5
Pour être juste, la réponse ci-dessus indique que vous avez besoin du parent PreferenceCategory.
mat

49

Dans le cas où la préférence est un enfant direct de l'écran des préférences, voici un code autonome:

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

4
Cela ne fonctionnera pas si la préférence est située dans la catégorie. vous devez findPreferencepour la catégorie et supprimer la préférence de la catégorie
MBH

1
@MBH: Merci d'avoir mentionné cette mise en garde!
1 '' du

9

Si vous voulez quelque chose qui changera dynamiquement les préférences, par exemple sur un SwitchPreference, j'ai trouvé que le meilleur moyen est de mettre toutes mes sous-options dans deux conteneurs de catégorie. Au départ, tout sera affiché, puis supprimez simplement les bits dont vous ne voulez pas. Le plus intelligent, c'est que vous déclenchez simplement la recréation lorsque quelque chose change et que vous n'avez pas à créer manuellement quoi que ce soit ou à vous soucier de remettre les choses dans le bon ordre.

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

Le seul inconvénient que je peux voir avec cela, c'est qu'il y a un flash car l'écran est recréé à partir de zéro.


Le cas ne fonctionne pas, du moins pas dans 22. Mais le changer en préférence (même s'il s'agit d'un regroupement de préférences) fonctionne.
Rob

Rob, je viens de tester le code ci-dessus dans un AVD API22 et cela fonctionne très bien. Assurez-vous que le contenu XML de vos préférences correspond à votre code. Pour l'exemple ci-dessus, SwitchPreference peut être n'importe où, mais vous avez besoin que les PreferenceCategorys soient des enfants directs de PreferenceScreen.
James

Je viens de recevoir la catégorie en tant que préférence, pas de distribution, et je l'ai supprimée. Travaillé.
Rob

8

Dans votre fichier 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>

Dans votre code:

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

8

Si vous utilisez PreferenceFragmentCompat, vous pouvez définir la visibilité en xml.

Les préférences de votre xml seront automatiquement converties en versions AppCompat. Vous pouvez ensuite utiliser l' attribut ' app: isPreferenceVisible ' dans votre xml

preferences.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" />

...

L'attribut est documenté sur https://developer.android.com/guide/topics/ui/settings/components-and-attributes

L'ajout PreferenceFragmentCompatest documenté sur https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy

Exemple:

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


3

Dans le fichier XML, vous pouvez créer une préférence masquée en laissant les balises de titre et de résumé vides.

<EditTextPreference
    android:defaultValue="toddlerCam"
    android:key="save_photo_dir"
/>

C'est la réponse parfaite pour moi. Je cherchais ça. Je vous remercie!
夏 期 劇場

2

Voici une façon générique de faire cela qui fonctionne indépendamment du fait que la préférence soit sous PreferenceCategoryou PreferenceScreen.

private void removePreference(Preference preference) {
    PreferenceGroup parent = getParent(getPreferenceScreen(), preference);
    if (parent == null)
        throw new RuntimeException("Couldn't find preference");

    parent.removePreference(preference);
}

private PreferenceGroup getParent(PreferenceGroup groupToSearchIn, Preference preference) {
    for (int i = 0; i < groupToSearchIn.getPreferenceCount(); ++i) {
        Preference child = groupToSearchIn.getPreference(i);

        if (child == preference)
            return groupToSearchIn;

        if (child instanceof PreferenceGroup) {
            PreferenceGroup childGroup = (PreferenceGroup)child;
            PreferenceGroup result = getParent(childGroup, preference);
            if (result != null)
                return result;
        }
    }

    return null;
}


0

Vous pouvez le faire de 2 manières:

1.Si vous utilisez la bibliothèque de support, vous pouvez créer une carte de l'arborescence des préférences et de leurs parents, puis supprimer une préférence en utilisant son parent. Voici une fonction pour générer une telle carte:

public static Map<Preference, PreferenceGroup> buildPreferenceParentTree(@NonNull final PreferenceScreen preferenceScreen) {
    final Map<Preference, PreferenceGroup> result = new HashMap<>();
    final Stack<PreferenceGroup> curParents = new Stack<>();
    curParents.add(preferenceScreen);
    while (!curParents.isEmpty()) {
        final PreferenceGroup parent = curParents.pop();
        final int childCount = parent.getPreferenceCount();
        for (int i = 0; i < childCount; ++i) {
            final Preference child = parent.getPreference(i);
            result.put(child, parent);
            if (child instanceof PreferenceGroup)
                curParents.push((PreferenceGroup) child);
        }
    }
    return result;
}
  1. Si vous utilisez la nouvelle API de préférences android-x, vous pouvez simplement définir la visibilité en utilisant la fonction setVisible .

Selon la documentation et la réponse de Tea setVisible() est disponible depuis la version 24.1.0 de la bibliothèque de support.
JJD

Avez-vous regardé ce que j'ai écrit? J'ai spécifiquement écrit que c'est possible maintenant ... De plus, la première solution aide à la suppression, ce qui est un peu différent de la dissimulation.
développeur android

Oui, j'ai lu votre réponse. Je faisais référence à votre deuxième point. Il se lit comme si la setVisibile()méthode était disponible à partir de android-x que j'ai essayé de clarifier. Aucune offense s'il vous plaît.
JJD

Android-X est celui qui remplace toutes les bibliothèques de support. Il n'y aura pas de nouvelles versions de la bibliothèque de support telles que nous les connaissons.
développeur android

Correct. J'en suis conscient . Pourtant, les personnes qui sont coincées avec les anciennes versions peuvent utiliser la méthode.
JJD

0

Si vous souhaitez évaluer, et sur la base de ce masque, une alternative peut être

SwitchPreference autenticacionUsuario = 
    (SwitchPreference) findPreference("key_autenticacion_usuario");

final EditTextPreference Username = 
    (EditTextPreference) findPreference("key_username_mqtt");
final EditTextPreference Password = 
    (EditTextPreference) findPreference("key_password_mqtt");

if (!autenticacionUsuario.isChecked()) {
    PreferenceCategory preferenceCategory = 
        (PreferenceCategory) findPreference("category_mqtt");
    preferenceCategory.removePreference(Username);
    preferenceCategory.removePreference(Password);
}

Tout cela doit être à l'intérieur

public static class PrefsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

1
Désolé, mais c'est un site en anglais. Pouvez-vous répondre en anglais?
Dave Schweisguth

Bien sûr, mon intention était aussi de pourvoir aux personnes qui ne parlent pas anglais
Gustavo Eduardo Belduma

3
@GustavoEduardoBelduma alors vous devrez peut-être lire ce meta.stackoverflow.com/a/297680/545026
Leo soutient Monica Cellio le

0

Si vous faites ce que je pense que vous essayez de faire (parce que j'essaye de le faire maintenant), il vaudrait peut-être mieux activer / désactiver la préférence. Parce que sa suppression le retire de l'écran des préférences et vous ne pourrez peut-être pas le rajouter où vous le souhaitez si vous avez créé l'écran par programme.

pref.setEnabled (false); pref.setEnabled (vrai);

bien que cela puisse être obsolète. Cela fonctionne pour le cas d'utilisation que je traverse actuellement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.