有没有一种方法可以动态显示和隐藏偏好设置? 在我的情况下,我有一个复选框首选项,它会禁用或启用两个首选项组(“带障碍”和“不带障碍”组之一)。 虽然这在桌面环境中是理想的GUI,但“带障碍”几乎占据了整个屏幕,而另一个“不带障碍”的只占据了屏幕的一小部分。
与其同时显示两个组,我想一次只显示其中一个,并根据复选框更改动态显示或隐藏两个组。 有没有一种方法可以实现这个功能?
有没有一种方法可以动态显示和隐藏偏好设置? 在我的情况下,我有一个复选框首选项,它会禁用或启用两个首选项组(“带障碍”和“不带障碍”组之一)。 虽然这在桌面环境中是理想的GUI,但“带障碍”几乎占据了整个屏幕,而另一个“不带障碍”的只占据了屏幕的一小部分。
与其同时显示两个组,我想一次只显示其中一个,并根据复选框更改动态显示或隐藏两个组。 有没有一种方法可以实现这个功能?
从PreferenceActivity调用
Preference somePreference = findPreference(SOME_PREFERENCE_KEY);
PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.removePreference(somePreference);
你以后可以调用:
preferenceScreen.addPreference(somePreference);
唯一有点棘手的部分是在添加回去时正确排序。请查看PreferenceScreen文档,尤其是它的基类PreferenceGroup,以获取详细信息。
注意:上述仅适用于PreferenceScreen
的直接子项。如果中间有PreferenceCategory
,则需要从其父PreferenceCategory
中删除首选项,而不是PreferenceScreen
。首先确保在XML文件中PreferenceCategory
设置了一个android:key
属性,然后执行以下操作:Preference somePreference = findPreference(SOME_PREFERENCE_KEY);
PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference(SOME_PREFERENCE_CATEGORY_KEY);
preferenceCategory.removePreference(somePreference);
并且:
preferenceCategory.addPreference(somePreference);
findPreference()
将不再找到之前已删除的首选项。 - user149408如果您只想根据另一个首选项来禁用/启用首选项,则可以指定 android:dependency="preferenceKey"
或 Preference.setDependency(String)
。
以下是来自developer.android.com的示例:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="pref_sync"
android:title="@string/pref_sync"
android:summary="@string/pref_sync_summ"
android:defaultValue="true" />
<ListPreference
android:dependency="pref_sync"
android:key="pref_syncConnectionType"
android:title="@string/pref_syncConnectionType"
android:dialogTitle="@string/pref_syncConnectionType"
android:entries="@array/pref_syncConnectionTypes_entries"
android:entryValues="@array/pref_syncConnectionTypes_values"
android:defaultValue="@string/pref_syncConnectionTypes_default" />
</PreferenceScreen>
我建议使用V7 preference,它有setVisible()
方法。但我还没有尝试过。
public class RemovablePreference extends Preference {
@Override
protected void onBindView(View view) {
super.onBindView(view);
updateVisibility(); // possibly a better place available?
}
private void updateVisibility() {
Context context = getContext(); // should be a PreferenceActivity
if (context instanceof PreferenceActivity) {
updateVisibility((PreferenceActivity)context);
}
}
private void updateVisibility(PreferenceActivity activity) {
updateVisibility(getPreferenceScreen(activity));
}
private PreferenceScreen getPreferenceScreen(PreferenceActivity activity) {
if (activity.getPreferenceScreen() != null) {
return activity.getPreferenceScreen(); // for old implementations
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
Fragment fragment = activity.getFragmentManager().findFragmentById(android.R.id.content);
if (fragment instanceof PreferenceFragment) {
return ((PreferenceFragment) fragment).getPreferenceScreen();
}
}
return null;
}
private void updateVisibility(PreferenceScreen screen) {
if (!isVisible() && screen != null) {
hidePreference(screen, this);
}
}
private boolean hidePreference(PreferenceGroup prefGroup, Preference removedPreference) {
boolean removed = false;
if (prefGroup.removePreference(removedPreference)) {
removed = true;
}
for (int i = 0; i < prefGroup.getPreferenceCount(); i++) {
Preference preference = prefGroup.getPreference(i);
if (preference instanceof PreferenceGroup) {
PreferenceGroup prefGroup2 = (PreferenceGroup)preference;
if (hidePreference(prefGroup2, this)) {
// The whole group is now empty -> remove also the group
if (prefGroup2.getPreferenceCount() == 0) {
removed = true;
prefGroup.removePreference(prefGroup2);
}
}
}
}
return removed;
}
protected boolean isVisible() {
return true; // override
}
findPreference(getString(R.string.pref_key)).setLayoutResource(R.layout.hidden);
getActivity().recreate();
希望这对你有所帮助。
R.layout.hidden
似乎是一个自定义布局。你能分享一下吗?另外,如果要撤销此操作,可能需要找出首选项项目使用的默认布局并重新分配它。 - user149408findPreference("pref_show_extra_stuff").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
findPreference("pref_extra_stuff_01").setVisible((Boolean) newValue);
findPreference("pref_extra_stuff_02").setVisible((Boolean) newValue);
return true;
}
});
pref_extra_stuff_01和pref_extra_stuff_02是两个偏好设置,当pref_show_extra_stuff被切换时会隐藏。
不要在设置界面的onCreate中执行这个操作:
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, new SettingsFragment()).commit();
settingsFragment = new SettingsFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, settingsFragment).commit();
然后,你可以使用一个全局的SharedPreferences.OnSharedPreferenceChangeListener来设置当你更改偏好时应该显示或隐藏什么内容:
// Global SharedPreferences.OnSharedPreferenceChangeListener
sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener()
{
Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key)
{
if (key.equals("switch key"))
{
boolean newPref = preferences.getBoolean("switch key", true);
settingsFragment.findPreference("seekbar key").setVisible(newPref);
}
}
};
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
然后在设置片段的onCreate中,您可以像这样做,根据现有的首选项设置应该隐藏什么:
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
if (!sharedPreferences.getBoolean("switch key", true)
{
SeekBarPreference seekBarPreference = findPreference("seekbar key");
seekBarPreference.setVisible(false);
}