PreferenceScreen android:summary update !

14
在我的 Android 应用中,我有一个父级 PreferenceScreen,它有3个 CheckBoxPreferences 作为子级。
当我点击父级 PreferenceScreen 时,会显示3个复选框,我选择其中一个,在与复选框关联的 Preference.OnPreferenceChangeListener 中,我使用以下代码设置父级 PreferenceScreen 的摘要:
Parent.setSummary("string depending on the selection")

问题是当我返回到父级时,它的摘要没有更新,即使内部值已经相应地更改为设置的值。

有人对此行为有任何想法吗?


需要注意的一点是,如果感兴趣的偏好本身是 CheckBoxPreference(或其他 TwoStatePreference,例如 SwitchPreference),那么如果已经分配了 android:summaryOnandroid:summaryOff,则 setSummary 将不起作用。在这种情况下应该使用 setSummaryOnsetSummaryOff,但我认为这并不明显。 - Stan
6个回答

14

使用

Parent.setSummary("string depending on the selection");
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();

这个工具非常好用,可以在任何更改摘要的地方使用。


如果屏幕嵌套在其他屏幕中,则应该在直接父屏幕上执行此操作。 - Learn OpenGL ES

2

这是正确的方式

Preference pref = findPreference(getString(R.string.key_of_pref));
PreferenceScreen parent = (PreferenceScreen) sf.findPreference(getString(R.string.key_of_preference_screen));
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
   @Override
   public boolean onPreferenceChange(Preference preference, Object newValue) {
       boolean newValueBool = (Boolean) newValue;
       parent.setSummary(newValueBool ? "Summary is true" : "Summary is false");                                                  
       ((BaseAdapter) getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
       // true to update the state of the Preference with the new value
       // in case you want to disallow the change return false
       return true;
  }
});

1

1

我发现似乎可以通过在setSummary()后跟getListView().invalidate()来使其工作。


1
如果您使用支持偏好设置,则选择以下内容:

findPreference("your_preference").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {

            public boolean onPreferenceChange(Preference preference, Object o) {
                getListView().getAdapter().notifyDataSetChanged();
                return true;
            }
        });

0

新的坚持使用片段而不是活动似乎使这更加困难。无效化路线似乎没有起作用,也没有使用底层视图的方法。感谢halxinate的答案,我现在已经成功解决了这个问题。对于像我一样对所有这些都很陌生的人来说,这里有更多细节:

创建设置片段时,在您的主要活动中保存一个引用,例如:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    switch (item.getItemId()) {
    case R.id.action_preferences:
        if (getFragmentManager().getBackStackEntryCount() < 1) {
            FragmentTransaction trans = getFragmentManager()
                    .beginTransaction();
            // Save a reference to the settings fragment
            settingsFrag = new SettingsFragment();
            trans.replace(R.id.container, settingsFrag);
            trans.addToBackStack(null);
            trans.commit();
        }
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

然后,当您想要从OnSharedPreferenceChangeListener更新外部PreferenceScreen的摘要时,请使用以下这种方式。请注意,您需要在偏好设置片段XML中为外部PreferenceScreen定义一个键(在本例中为android:key="prefs_root"):

public static void setOuterSummaries(SettingsFragment sf) {
    // Set the outer preferences summaries
    if (sf == null)
        return;
    //Code to update the summaries....

    // Force the parent screen summaries to update
    prefScr = (PreferenceScreen) sf.findPreference("prefs_root");
    if (prefScr != null)
            ((BaseAdapter) prefScr.getRootAdapter()).notifyDataSetChanged();

}

OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
    public void onSharedPreferenceChanged(SharedPreferences prefs,
            String key) {
        Log.e("L", "Change");
        setOuterSummaries(settingsFrag);
    }
};

请注意,您可以保存对BaseAdapter的引用,而不是设置片段的引用,但是当您考虑将其推广到多片段情况或动态创建片段内容的代码时,这种方法似乎更安全。

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