Usuń / ukryj preferencję z ekranu

134

Mam działanie, które rozszerza PreferenceActivity. Ładuję preferencje z pliku xml. Ale w niektórych przypadkach muszę całkowicie ukryć jedną z preferencji na ekranie na podstawie stanu mojej aplikacji. Istnieje metoda setEnabled, ale nie jest to dokładnie to, czego chcę. Chcę całkowicie usunąć tę preferencję z ekranu. Czy to możliwe ?

Alex Volovoy
źródło

Odpowiedzi:

171

Tak, jeśli masz odniesienie zarówno do Preference, jak i do jego elementu nadrzędnego (a PreferenceCategorylub PreferenceScreen)

myPreferenceScreen.removePreference(myPreference);
David Hedlund
źródło
Wspaniały! Dzięki! Działa i ma sens
Bostone
Mogłem przez to odpowiedzieć na własne pytanie? stackoverflow.com/a/4704360/956975
marienke
2
Niestety, trwale usuwa preferencję. Czy można to po prostu ukryć?
Dmitry
U mnie też nie działa. Preferencja pozostaje!
Dmitry
@Dmitry Możesz to po prostu setEnabled()
wyszarzać
212

Jeśli Preferenceznajdujesz się w a PreferenceCategory, musisz to zrobić:

XML:

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

    <CheckBoxPreference
        android:key="checkPref" />

Jawa:

CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
mCategory.removePreference(mCheckBoxPref);
Kavi
źródło
5
Szczerze mówiąc, powyższa odpowiedź mówi, że potrzebujesz rodzica PreferenceCategory.
mat.
49

W przypadku, gdy preferencja jest bezpośrednim elementem podrzędnym ekranu preferencji, poniżej znajduje się samodzielny kod:

PreferenceScreen screen = getPreferenceScreen();
Preference pref = getPreferenceManager().findPreference("mypreference");
screen.removePreference(pref);
1 ''
źródło
4
To nie zadziała, jeśli preferencja znajduje się w kategorii. musisz findPreferencedla kategorii i usuń preferencję z kategorii
MBH
1
@MBH: Dziękuję za wspomnienie o tym zastrzeżeniu!
1 ''
9

Jeśli chcesz czegoś, co dynamicznie zmieni preferencje, na przykład w SwitchPreference, znalazłem najlepszy sposób, aby umieścić wszystkie moje opcje podrzędne w dwóch kontenerach kategorii. Początkowo będziesz miał wszystko pokazane, a potem po prostu usuniesz niepotrzebne fragmenty. Sprytne jest to, że po prostu uruchamiasz odtwarzanie, gdy coś się zmienia, a potem nie musisz niczego ręcznie tworzyć ani martwić się o umieszczenie rzeczy z powrotem we właściwej kolejności.

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

Jedynym minusem, jaki widzę w tym, jest flash, ponieważ ekran jest odtwarzany od zera.

James
źródło
Sprawa nie działa, przynajmniej nie w 22. Ale zmiana jej na Preference (nawet jeśli jest to grupa preferencji) działa.
Rob
Rob, właśnie przetestowałem powyższy kod w API22 AVD i działa dobrze. Upewnij się, że zawartość XML preferencji jest zgodna z kodem. W powyższym przykładzie SwitchPreference może znajdować się w dowolnym miejscu, ale PreferenceCategorys musi być bezpośrednimi elementami podrzędnymi PreferenceScreen.
James
Właśnie wybrałem kategorię jako preferencję, bez obsady i usunąłem ją. Pracował.
Rob
8

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

W swoim kodzie:

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
user3165739
źródło
8

Jeśli używasz PreferenceFragmentCompat , możesz ustawić widoczność w xml.

Preferencje w Twoim xml zostaną automatycznie przekonwertowane na wersje AppCompat. Następnie możesz użyć atrybutu „ app: isPreferenceVisible ” w swoim pliku XML

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

...

Atrybut jest udokumentowany pod adresem https://developer.android.com/guide/topics/ui/settings/components-and-attributes

Dodawanie PreferenceFragmentCompatjest udokumentowane na https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy

Przykład:

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();
    }
} 
aaronvargas
źródło
3

W pliku XML możesz ustawić ukryte preferencje, pozostawiając tytuł i tagi podsumowania puste.

<EditTextPreference
    android:defaultValue="toddlerCam"
    android:key="save_photo_dir"
/>
Al Ro
źródło
To dla mnie doskonała odpowiedź. Szukałem tego. Dziękuję Ci!
夏 期 劇場
2

Oto ogólny sposób na zrobienie tego, który działa niezależnie od tego, czy preferencja jest pod a, PreferenceCategoryczy 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;
}
Sam
źródło
0

Możesz to zrobić na dwa sposoby:

Jeśli korzystasz z biblioteki wsparcia, możesz zbudować mapę drzewa preferencji i ich rodziców, a następnie usunąć preferencję, używając jej rodzica. Oto funkcja do wygenerowania takiej mapy:

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. Jeśli używasz nowego interfejsu API preferencji android-x, możesz po prostu ustawić widoczność, używając na nim funkcji setVisible .
programista Androida
źródło
Zgodnie z docs i odpowiedź Tea setVisible() jest dostępny od wersji 24.1.0 biblioteki Wsparcia.
JJD
Czy spojrzałeś na to, co napisałem? Specjalnie napisałem, że jest to teraz możliwe ... Poza tym pierwsze rozwiązanie pomaga w usuwaniu, które jest trochę inne niż ukrywanie ...
programista android
Tak, przeczytałem twoją odpowiedź. Miałem na myśli twój drugi punkt. Czyta się tak, jakby setVisibile()metoda była dostępna w systemie Android-x, co próbowałem wyjaśnić. Bez obrazy, proszę.
JJD
Android-X zastąpi wszystkie obsługiwane biblioteki. Nie będzie żadnych nowych wersji biblioteki wsparcia, jakie znamy.
programista Androida
Poprawny. Jestem tego świadomy . Jednak osoby, które są skazane na wcześniejsze wersje, mogą skorzystać z tej metody.
JJD
0

Jeśli chcesz ocenić i na podstawie tej maski, może być alternatywą

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

Wszystko to musi być w środku

public static class PrefsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
Gustavo Eduardo Belduma
źródło
1
Przepraszamy, ale to jest witryna w języku angielskim. Czy możesz odpowiedzieć po angielsku?
Dave Schweisguth
Oczywiście moim zamiarem było również zapewnienie ludziom, którzy nie mówią po angielsku
Gustavo Eduardo Belduma
3
@GustavoEduardoBelduma, być może będziesz musiał przeczytać ten meta.stackoverflow.com/a/297680/545026
Leo obsługuje Monikę Cellio
0

Jeśli robisz to, co myślę, że próbujesz zrobić (ponieważ próbuję to zrobić teraz), może być lepiej włączyć / wyłączyć tę preferencję. Ponieważ usunięcie go usuwa go z ekranu preferencji i możesz nie być w stanie dodać go tam, gdzie chcesz, jeśli utworzyłeś ekran programowo.

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

chociaż może to być przestarzałe. Działa w przypadku użycia, przez który teraz przechodzę.

RCB
źródło