Entfernen / Ausblenden einer Voreinstellung vom Bildschirm


134

Ich habe eine Aktivität, die PreferenceActivity erweitert. Ich lade Einstellungen aus der XML-Datei. In einigen Fällen muss ich jedoch eine der Einstellungen basierend auf meinem App-Status vollständig vom Bildschirm ausblenden. Es gibt eine setEnabled-Methode, aber es ist nicht genau das, was ich will. Ich möchte diese Einstellung vollständig vom Bildschirm entfernen. Ist es möglich ?

Antworten:


171

Ja, wenn Sie einen Verweis sowohl auf das Preferenceals auch auf das übergeordnete Element (a PreferenceCategoryoder PreferenceScreen) haben.

myPreferenceScreen.removePreference(myPreference);

Toll! Vielen Dank! Funktioniert und macht vollkommen Sinn
Bostone

Ich hätte meine eigene Frage damit beantworten können? stackoverflow.com/a/4704360/956975
marienke

2
Leider wird die Präferenz dauerhaft entfernt. Kann man es einfach verstecken?
Dmitry

Es funktioniert auch nicht bei mir. Die Präferenz bleibt!
Dmitry

@Dmitry Du kannst es einfach grau machen mitsetEnabled()
JakeD

212

Wenn Sie Preferencesich innerhalb eines befinden PreferenceCategory, müssen Sie Folgendes tun:

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
Um fair zu sein, sagt die obige Antwort, dass Sie den Elternteil brauchen PreferenceCategory.
Matt

49

Für den Fall, dass die Voreinstellung ein direktes untergeordnetes Element des Einstellungsbildschirms ist, finden Sie hier einen eigenständigen Code:

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

4
Dies funktioniert nicht, wenn sich die Einstellung innerhalb der Kategorie befindet. Sie müssen findPreferencefür die Kategorie, und entfernen Sie die Präferenz aus der Kategorie
MBH

1
@MBH: Danke, dass du diesen Vorbehalt erwähnt hast!
1 ''

9

Wenn Sie etwas möchten, das die Einstellungen dynamisch ändert, z. B. in einer SwitchPreference, habe ich festgestellt, dass es am besten ist, alle meine Unteroptionen in zwei Kategoriecontainer zu packen. Zuerst wird alles angezeigt, dann entfernen Sie einfach die Bits, die Sie nicht möchten. Das Schlaue ist, dass Sie nur eine Neuerstellung auslösen, wenn sich etwas ändert, und dann nichts manuell erstellen oder sich darum kümmern müssen, die Dinge wieder in die richtige Reihenfolge zu bringen.

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

Der einzige Nachteil, den ich dabei sehen kann, ist ein Blitz, wenn der Bildschirm von Grund auf neu erstellt wird.


Der Fall funktioniert nicht, zumindest nicht in 22. Aber das Ändern in eine Voreinstellung (obwohl es sich um eine Gruppierung von Voreinstellungen handelt) funktioniert.
Rob

Rob, ich habe gerade den obigen Code in einer API22 AVD getestet und er funktioniert einwandfrei. Stellen Sie sicher, dass Ihr bevorzugter XML-Inhalt mit Ihrem Code übereinstimmt. Für das obige Beispiel kann sich die SwitchPreference an einer beliebigen Stelle befinden. Sie benötigen jedoch die PreferenceCategorys, um direkte untergeordnete Elemente des PreferenceScreen zu sein.
James

Ich habe gerade die Kategorie als Präferenz erhalten, keine Besetzung, und sie entfernt. Hat funktioniert.
Rob

8

In Ihrer XML-Datei:

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

In Ihrem 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

Wenn Sie PreferenceFragmentCompat verwenden , können Sie die Sichtbarkeit in XML festlegen.

Die Einstellungen in Ihrer XML werden automatisch in AppCompat-Versionen konvertiert. Sie können dann das Attribut ' app: isPreferenceVisible ' in Ihrer XML verwenden

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

...

Das Attribut ist unter https://developer.android.com/guide/topics/ui/settings/components-and-attributes dokumentiert

Das Hinzufügen PreferenceFragmentCompatist unter https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy dokumentiert

Beispiel:

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

In der XML-Datei können Sie eine versteckte Einstellung vornehmen, indem Sie die Titel- und Zusammenfassungs-Tags leer lassen.

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

Dies ist die perfekte Antwort für mich. Ich habe danach gesucht. Danke dir!
期 劇場

2

Hier ist eine generische Methode, die unabhängig davon funktioniert, ob die Einstellung unter a PreferenceCategoryoder liegt 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

Sie können dies auf zwei Arten tun:

1.Wenn Sie die Unterstützungsbibliothek verwenden, können Sie eine Karte des Baums der Einstellungen und ihrer Eltern erstellen und dann eine Präferenz mithilfe ihrer Eltern entfernen. Hier ist eine Funktion zum Generieren einer solchen Karte:

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. Wenn Sie die neue Android-X-Einstellungs-API verwenden, können Sie die Sichtbarkeit einfach mithilfe der Funktion setVisible festlegen .

Laut Dokumentation und Tea's Antwort setVisible() ist seit Version 24.1.0 der Support-Bibliothek verfügbar.
JJD

Hast du dir angesehen, was ich geschrieben habe? Ich schrieb speziell, dass es jetzt möglich ist ... Auch die erste Lösung hilft beim Entfernen, was ein bisschen anders ist als das Verstecken ..
Android-Entwickler

Ja, ich habe deine Antwort gelesen. Ich bezog mich auf Ihren 2. Punkt. Es liest sich so, als ob die setVisibile()Methode von Android-X verfügbar ist, was ich zu klären versuchte. Nichts für ungut bitte.
JJD

Android-X ersetzt alle Support-Bibliotheken. Es wird keine neuen Versionen der Support-Bibliothek geben, wie wir sie kennen.
Android-Entwickler

Richtig. Ich bin mir dessen bewusst . Dennoch können Personen, die mit früheren Versionen nicht weiterkommen, von der Methode Gebrauch machen.
JJD

0

Wenn Sie bewerten möchten und basierend auf dieser Maske, kann eine Alternative sein

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

All dies muss innerhalb sein

public static class PrefsFragment extends PreferenceFragment {

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

1
Sorry, aber dies ist eine englische Seite. Können Sie auf Englisch antworten?
Dave Schweisguth

Natürlich wollte ich auch für Leute sorgen, die kein Englisch sprechen
Gustavo Eduardo Belduma

3
@GustavoEduardoBelduma dann müssen Sie möglicherweise diese meta.stackoverflow.com/a/297680/545026
Leo unterstützt Monica Cellio

0

Wenn Sie das tun, was Sie meiner Meinung nach versuchen (weil ich es jetzt versuche), ist es möglicherweise besser, die Einstellung zu aktivieren / deaktivieren. Durch das Entfernen wird es aus dem Einstellungsbildschirm entfernt und Sie können es möglicherweise nicht wieder an der gewünschten Stelle hinzufügen, wenn Sie den Bildschirm programmgesteuert erstellt haben.

pref.setEnabled (false); pref.setEnabled (true);

obwohl dies veraltet sein könnte. Es funktioniert für den Anwendungsfall, den ich gerade durchlaufe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.