web-dev-qa-db-fra.com

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

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

127
Alex Volovoy

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

myPreferenceScreen.removePreference(myPreference);
168
David Hedlund

Si votre Preference est dans une 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);
201
Kavi

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

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

Si vous voulez quelque chose qui modifiera dynamiquement les préférences, par exemple sur un SwitchPreference, j'ai trouvé le meilleur moyen de placer toutes mes sous-options dans des conteneurs de deux catégories. Au départ, vous aurez tout affiché, puis vous supprimerez simplement les bits que vous ne voulez pas. Le plus malin, c’est que vous déclenchez simplement la recréation lorsque quelque chose change, sans avoir à créer manuellement quoi que ce soit, ni à 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.

8
James

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
7
user3165739

Je recommande d'utiliser la préférence v7, elle a la méthode setVisible(). Mais je n'ai pas encore essayé. En conséquence, vous devez utiliser PreferenceFragment au lieu de PreferenceActivity

3
Tea

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

Les préférences de votre fichier xml seront automatiquement converties en versions AppCompat. Vous pouvez ensuite utiliser l'attribut 'app: isPreferenceVisible' dans votre fichier 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é à https://developer.Android.com/guide/topics/ui/settings/components-and-attributes

L'ajout de PreferenceFragmentCompat est documenté à 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
aaronvargas

Dans le fichier XML, vous pouvez créer une préférence masquée en laissant vides les balises title et summary. 

<EditTextPreference
    Android:defaultValue="toddlerCam"
    Android:key="save_photo_dir"
/>
2
Al Ro

Voici une manière générique de le faire qui fonctionne, que la préférence soit sous PreferenceCategory ou 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;
}
1
Sam

Depuis l'API Android 26, la méthode getParent() est disponible: https://developer.Android.com/reference/Android/preference/Preference.html#getParent ()

Bien que vous puissiez faire ce qui suit:

preference.getParent().removePreference(preference);
1
birdy

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

Vous pouvez le faire de deux manières:

1. Si vous utilisez la bibliothèque de support, vous pouvez créer une carte de l’arbre 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 setVisible function.
0