如何通过编程方式删除PreferenceCategory?

42

我需要在程序中移除一个PreferenceCategory。虽然我可以使用以下代码移除单个的Preference,但是我需要移除(禁用)整个PreferenceCategory。

PreferenceScreen preferenceScreen = getPreferenceScreen();
EditTextPreference etp = (EditTextPreference) preferenceScreen.findPreference("pref22");
((PreferenceGroup) findPreference("prefcat")).removePreference(etp);

编辑: 这是一个针对PreferenceCategory "prefcat"和子偏好设置"pref22"的工作代码:

PreferenceScreen preferenceScreen = getPreferenceScreen();
EditTextPreference etp = (EditTextPreference) preferenceScreen.findPreference("pref22");

PreferenceGroup preferenceGroup = (PreferenceGroup) findPreference("prefcat");
if (preferenceGroup != null) {
    preferenceGroup.removePreference(etp);
    preferenceScreen.removePreference(preferenceGroup);
}

我在这里不清楚的是,您正在询问PreferenceCategory,但您的解决方案涉及删除preferenceGroup。我有同样的情况...为了澄清,我的XML列出了preferenceCategory,但我要摆脱那个标题/组,我像您一样以编程方式检索到我的preferenceCategory引用,并进行PreferenceGroup声明。希望这能帮助其他人。 - taraloca
哦,很久以前了。如果你看代码,你会发现类别被转换为PreferenceGroup。 - Harald Wilhelm
4个回答

76

您可以通过获取对PreferenceScreen的引用来隐藏类别:

在您的XML中:

<PreferenceScreen 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:key="@string/preferenceScreen">

//set all you values
//Preference, PreferenceCategory and/or CheckBoxPreference

</PreferenceScreen>

在你的string.xml文件中:

不要忘记设置这个新字符串

 <string name="preferenceScreen" translatable="false">preferenceScreen</string>

在你的代码中:

preferenceScreen = (PreferenceScreen) findPreference(getResources().getString(R.string.preferenceScreen));

然后从您的PreferenceScreen中删除该类别:

myCategory = (PreferenceCategory) findPreference(getResources().getString(R.string.my_category));
myPreferenceScreen.removePreference(myCategory);

使用PreferenceCategory对我没有起作用,但是将其转换为PreferenceGroup就可以了。 - Mr. Bungle
9
应该选择这个作为答案。 - xmen
1
请ن½؟用myPreferenceScreen.removePreference(myCategory);,ه› ن¸؛首选é،¹ه±ڈه¹•ن¸ٹن¸چه­کهœ¨remove()و–¹و³•م€‚ - Tomask

17

在XML中为您的PreferenceScreen和PreferenceCategory提供键:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="preferenceScreen" >

  <PreferenceCategory
     android:summary="@string/settings_billing_summary"
     android:title="Title"
     android:key="myPrefCat" >
      <Preference
      android:key="someKey"
      android:summary="Sum"
      android:title="Title" />
   </PreferenceCategory>

</PreferenceScreen>

现在您可以从您的类中引用 preferenceScreen 和 preferenceCategory 并使用 removePreference() 方法从屏幕上移除偏好设置:

    PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
    PreferenceCategory myPrefCat = (PreferenceCategory) findPreference("myPrefCat");
    preferenceScreen.removePreference(myPrefCat);

这个答案基于 douarbou的回答,其看起来已经过时,但基本相同。


这对我帮助很大。但是我使用了myPrefCat.setVisible(false/false),因为我有一个只有在我点击复选框时才显示的类别。非常感谢,你让我的一天! - Tomas F.

17

不要一开始加载PreferenceCategory

如果您在Java中定义首选项,请勿创建PreferenceCategory

如果您在XML中定义首选项,请使用三个XML文件:

  1. 用于此类别之前的内容
  2. 用于魔术类别的内容
  3. 用于此类别之后的内容

在需要该类别的情况下,加载所有三个XML文件。在不需要该类别的情况下,仅加载第一个和第三个XML文件。


1
非常感谢。我会这样做的。仅供记录:是否有方法可以通过编程方式删除从XML加载的PreferenceCategory? - Harald Wilhelm
1
@hjw:我没有尝试过。我认为在类别上使用removePreference()会起作用,但我假设你已经尝试过了。此外,如果你不需要它,为什么要首先加载它呢? - CommonsWare
是的,你可以使用removePreference()函数。 - Ken Fehling
1
@CommonsWare,有没有其他方法可以在运行时删除类别,而不是创建三个文件? - Bipin Vayalu
1
@CommonsWare - FYI - 我创建了一个示例项目,演示如何以编程方式添加和删除PreferenceCategories。它并不太糟糕,并让您充分利用Android提供的功能,同时仍保持灵活性!https://github.com/markcerqueira/flexible_preferences - Mark
显示剩余5条评论

2
您可以通过遍历所有的偏好设置,然后检查您希望了解的任何偏好设置的父级,即使不使用父级的ID,也可以找到完整的子父级树:
public static Map<Preference,PreferenceGroup> buildPreferenceParentTree(final PreferenceActivity activity)
    {
    final Map<Preference,PreferenceGroup> result=new HashMap<Preference,PreferenceGroup>();
    final Stack<PreferenceGroup> curParents=new Stack<PreferenceGroup>();
    curParents.add(activity.getPreferenceScreen());
    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;
    }

示例用法:

  final Map<Preference,PreferenceGroup> preferenceParentTree=buildPreferenceParentTree(SettingsActivity.this);
  final PreferenceGroup preferenceGroup=preferenceParentTree.get(preferenceToRemove);
  preferenceGroup.removePreference(preferenceToRemove);

编辑:看起来这里有一个新的API:

https://developer.android.com/reference/androidx/preference/Preference#setVisible(boolean)

我不确定目前是否可用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接