代码之家  ›  专栏  ›  技术社区  ›  Alex Volovoy

从屏幕上删除/隐藏首选项

  •  128
  • Alex Volovoy  · 技术社区  · 14 年前

    我有一个扩展首选项活动的活动。 我正在从XML文件加载首选项。 但在某些情况下,我需要根据我的应用程序状态完全隐藏屏幕上的一个首选项。有一个setEnabled方法,但它不是我想要的。我想从屏幕上完全删除这个首选项。 有可能吗?

    12 回复  |  直到 5 年前
        1
  •  168
  •   darrenp David Hedlund    11 年前

    是的,如果您同时参考了 Preference 及其母公司(a PreferenceCategory PreferenceScreen )

    myPreferenceScreen.removePreference(myPreference);
    
        2
  •  201
  •   JJD    6 年前

    如果你 Preference 在一个 PreferenceCategory ,您必须这样做:

    XML:

    <PreferenceCategory
        android:key="category_foo"
        android:title="foo">
    
        <CheckBoxPreference
            android:key="checkPref" />
    

    爪哇:

    CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
    PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
    mCategory.removePreference(mCheckBoxPref);
    
        3
  •  44
  •   1''    11 年前

    如果首选项是首选项屏幕的直接子项,下面是一些独立代码:

    PreferenceScreen screen = getPreferenceScreen();
    Preference pref = getPreferenceManager().findPreference("mypreference");
    screen.removePreference(pref);
    
        4
  •  8
  •   James    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();
        }
    }
    

    我能看到的唯一缺点是,当屏幕从头重新创建时,会有一个闪光。

        5
  •  7
  •   JJD    6 年前

    在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
    
        6
  •  3
  •   JJD    6 年前

    我建议使用V7首选项,它有 setVisible() 方法。但我还没试过。因此你必须使用 PreferenceFragment 而不是 PreferenceActivity .

        7
  •  3
  •   aaronvargas    6 年前

    如果您正在使用 PreferenceFragmentCompat 您可以在XML中设置可见性。

    XML中的首选项将自动转换为AppCompat版本。然后您可以使用' 应用程序:isPreferenceVisible 'XML中的属性

    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();
        }
    } 
    
        8
  •  2
  •   Sam    7 年前

    这是一种通用的方法,不管偏好是否低于 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;
    }
    
        9
  •  2
  •   Neuron MonoThreaded    6 年前

    在XML文件中,您可以通过将标题和摘要标记保留为空来进行隐藏的首选项。

    <EditTextPreference
        android:defaultValue="toddlerCam"
        android:key="save_photo_dir"
    />
    
        10
  •  1
  •   amukhachov    6 年前

    自Android API 26以来 getParent() 方法可用: https://developer.android.com/reference/android/preference/Preference.html#getParent()

    尽管您可以执行以下操作:

    preference.getParent().removePreference(preference);
    
        11
  •  0
  •   android developer    6 年前

    您可以通过两种方式完成此操作:

    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. 如果您使用新的android-x首选项API,您可以使用 setVisible 对它起作用。
        12
  •  0
  •   Community basarat    5 年前

    如果您想评估,并基于该遮罩,可以选择

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