我有一个扩展PreferenceActivity的活动。我正在从xml文件加载首选项。但是在某些情况下,我需要根据我的应用程序状态从屏幕上完全隐藏首选项之一。有一个setEnabled方法,但这并不是我想要的。我想从屏幕上完全删除该首选项。可能吗 ?
我有一个扩展PreferenceActivity的活动。我正在从xml文件加载首选项。但是在某些情况下,我需要根据我的应用程序状态从屏幕上完全隐藏首选项之一。有一个setEnabled方法,但这并不是我想要的。我想从屏幕上完全删除该首选项。可能吗 ?
Answers:
是的,如果您同时引用Preference及其父级(a PreferenceCategory或PreferenceScreen)
myPreferenceScreen.removePreference(myPreference);setEnabled()
                    如果您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);PreferenceCategory。
                    如果您希望某些东西能够动态更改首选项,例如在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();
    }
}我可以看到的唯一缺点是,从头开始重新创建屏幕时会出现闪烁。
在您的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如果使用的是PreferenceFragmentCompat,则可以在xml中设置可见性。
xml中的首选项将自动转换为AppCompat版本。然后,您可以在XML中使用' app:isPreferenceVisible '属性
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();
    }
} 我建议使用v7首选项,它有setVisible()方法。但是我还没有尝试过。因此,您必须使用PreferenceFragment代替PreferenceActivity。
这是执行此操作的通用方法,无论首选项是否位于a 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;
}由于Android API 26 getParent()方法可用:https : //developer.android.com/reference/android/preference/Preference.html#getParent()
尽管您可以执行以下操作:
preference.getParent().removePreference(preference);您可以通过以下两种方式执行此操作:
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;
}setVisibile()方法可从我试图阐明的android-x中获得。请不要冒犯。
                    如果您要评估,并基于该掩码,则可以选择
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);