Видаліть / прихойте налаштування з екрана


134

У мене є діяльність, яка розширює PreferenceActivity. Я завантажую налаштування з файлу xml. Але в деяких випадках мені потрібно повністю приховати одне з налаштувань на екрані залежно від стану мого додатка. Існує метод setEnabled, але це не зовсім те, що я хочу. Я хочу видалити це налаштування з екрана повністю. Це можливо ?

Відповіді:


171

Так, якщо у вас є посилання на Preferenceбатьківський і його (а PreferenceCategoryабо PreferenceScreen)

myPreferenceScreen.removePreference(myPreference);

Чудово! Дякую! Працює і має ідеальний сенс
Бостон

Я, можливо, відповів на власне запитання через це? stackoverflow.com/a/4704360/956975
marienke

2
На жаль, це назавжди видаляє перевагу. Чи можна просто приховати це?
Дмитро

Це також не працює для мене. Перевага залишається!
Дмитро

@Dmitry Ви можете просто setEnabled()
сіріти

212

Якщо ваш номер Preferenceзнаходиться в межах PreferenceCategory, ви повинні зробити це:

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
Для справедливості, наведена вище відповідь говорить про те, що вам потрібен батько PreferenceCategory.
матовий

49

У випадку, коли налаштування є прямим дочірнім екраном налаштувань, ось окремий код:

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

4
Це не працює, якщо уподобання знаходиться всередині категорії. вам потрібно findPreferenceдля категорії і видаліть уподобання з категорії
MBH

1
@MBH: Дякую, що згадуєте про цей застереження!
1 ''

9

Якщо ви хочете щось, що буде динамічно змінювати префікси, наприклад, на SwitchPreference, я знайшов найкращий спосіб - помістити всі мої додаткові параметри в дві контейнери категорії. Спочатку у вас все буде показано, потім ви просто видалите біти, які вам не потрібні. Розумний біт, ви просто запускаєте відтворювати, коли щось змінюється, і тоді вам не потрібно нічого створювати вручну або турбуватися про те, щоб повернути речі в правильному порядку.

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

Єдиний недолік, який я бачу з цим, - це спалах, коли екран відтворюється з нуля.


Справа не працює, принаймні не в 22. Але змінити її на "Налаштування" (навіть якщо це групування уподобань) справді працює.
Роб

Роб, я щойно перевірив наведений вище код на API22 AVD, і він працює чудово. Переконайтеся, що ваші уподобання вмісту XML відповідають вашому коду. Для наведеного вище прикладу SwitchPreference може бути де завгодно, але вам потрібні категорії PreferenceCategorys, щоб бути прямими дітьми екрана PreferenceScreen.
Джеймс

Щойно я отримав категорію як «Налаштування», не відіграв її, і видалив її. Працювали.
Роб

8

У вашому 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>

У вашому коді:

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

Якщо ви використовуєте PreferenceFragmentCompat, ви можете встановити видимість у xml.

Налаштування у вашому xml автоматично перетворяться у версії AppCompat. Потім ви можете використовувати атрибут " app: isPreferenceVisible " у вашому 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" />

...

Атрибут задокументований на https://developer.android.com/guide/topics/ui/settings/components-and-attributes

Додавання PreferenceFragmentCompatзадокументовано на https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy

Приклад:

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

5

Я рекомендую використовувати перевагу v7, у ній є setVisible()метод. Але я ще цього не пробував. Відповідно, ви повинні використовувати PreferenceFragmentзамість цього PreferenceActivity.


Прийнята відповідь не працюватиме для V7. Використання setVisible працює для V7
m12lrpv

3

У XML-файлі ви можете зробити приховані налаштування, залишивши порожні заголовки та теги підсумками.

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

Це ідеальна відповідь для мене. Я шукав цього. Дякую!
夏 期

2

Ось загальний спосіб зробити це, який працює незалежно від того, чи є вподобання під PreferenceCategoryабо 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

Це можна зробити двома способами:

1. Якщо ви використовуєте бібліотеку підтримки, ви можете скласти карту дерева уподобань та їх батьків, а потім видалити уподобання за допомогою його батьків. Ось функція для створення такої карти:

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. Якщо ви використовуєте новий API налаштування Android-x, ви можете просто встановити видимість, використовуючи функцію setVisible .

Відповідно до документів і відповідь Tea setVisible() доступна з версії 24.1.0 бібліотеки підтримки.
JJD

Ви подивилися на те, що я написав? Я спеціально писав, що це можливо зараз ... Крім того, перше рішення допомагає при видаленні, яке трохи інакше, ніж приховування ..
android developer

Так, я прочитав вашу відповідь. Я мав на увазі ваш другий пункт. Він читає так, ніби setVisibile()метод доступний від android-x, який я намагався уточнити. Без образи, будь ласка.
JJD

Android-X замінює всі бібліотеки підтримки. Не буде нових версій бібліотеки підтримки, як ми їх знаємо.
андроїд розробник

Правильно. Я про це знаю . Тим не менш, люди, які застрягли в колишніх версіях, можуть скористатися методом.
JJD

0

Якщо ви хочете оцінити, і на основі цієї маски може бути альтернатива

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

Все це повинно бути всередині

public static class PrefsFragment extends PreferenceFragment {

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

1
Вибачте, але це англійський сайт. Ви можете відповісти англійською?
Дейв Швайсгут

Звичайно, мій намір також полягав у наданні людям, які не розмовляють англійською
Густаво Едуардо Белдума

3
@GustavoEduardoBelduma, то, можливо, вам доведеться прочитати цей meta.stackoverflow.com/a/297680/545026
Лев підтримує Моніку Челіо

0

Якщо ви робите те, що я думаю, що ви намагаєтесь зробити (тому що я намагаюся це зробити зараз), можливо, буде краще включити / відключити налаштування. Оскільки його видалення виймає його з екрана налаштувань, і ви, можливо, не зможете додати його назад, куди хочете, якби екран зробили програмно.

pref.setEnabled (помилково); pref.setEnabled (вірно);

хоча це може бути застарілим. Це працює для випадку використання, який я переживаю зараз.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.