4

我正在尝试使用片段构建我的 PreferenceActivity。我有一个包含两个 CheckBoxPreferences 的 PreferenceFragment:

<CheckBoxPreference
    android:key="pref_bfp_scale"
    android:title="@string/PREF_BFP_scale_title"
    android:defaultValue="false" />
<CheckBoxPreference
    android:key="pref_bfp_navy"
    android:title="@string/PREF_BFP_navy_title"
    android:defaultValue="true" />

我的 FragmentSettingsActivity:

public class FragmentSettingsActivity extends PreferenceActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public static class BodyFatPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_body_fat);
            bindPrefSumtoValListener(findPreference("pref_bfp_scale"), "Boolean");
            bindPrefSumtoValListener(findPreference("pref_bfp_navy"), "Boolean");
        }
    }

    private static Preference.OnPreferenceChangeListener prefSumtoValListener = new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) {
            String stringValue = value.toString();
            log("Pref changed - Value: " + stringValue);

            if (preference instanceof CheckBoxPreference) {
                Map<String, Integer> checkboxes = new HashMap<String, Integer>();

                checkboxes.put("pref_bfp_navy_unchecked", R.string.PREF_BFP_navy_summary_unchecked);
                checkboxes.put("pref_bfp_navy_checked", R.string.PREF_BFP_navy_summary_checked);
                checkboxes.put("pref_bfp_scale_unchecked", R.string.PREF_BFP_scale_summary_unchecked);
                checkboxes.put("pref_bfp_scale_checked", R.string.PREF_BFP_scale_summary_checked);

                log(Boolean.toString(((CheckBoxPreference) preference).isChecked()));
                log(String.format("? : %s_%s", preference.getKey(), ((CheckBoxPreference) preference).isChecked()? "checked" : "unchecked"));

                preference.setSummary(checkboxes.get(String.format("%s_%s", preference.getKey(), ((CheckBoxPreference) preference).isChecked()? "checked" : "unchecked")));
            }

            return true;

        }
    };

    private static void bindPrefSumtoValListener(Preference preference, String type) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(preference.getContext());

        preference.setOnPreferenceChangeListener(prefSumtoValListener);

        if (type.equals("Boolean")) {
            prefSumtoValListener.onPreferenceChange(preference, sharedPreferences.getBoolean(preference.getKey(), false));
        }
    }
}

onPreferenceChange 的第一次调用正确地设置了摘要,但其他所有调用都设置了相反的摘要:如果选中 Box,则设置“未选中”摘要,反之亦然。

似乎 isChecked() 返回了某种错误的值,因为 value.toString() 将正确的状态作为字符串返回。

log() 打印:

log("Pref changed - Value: " + stringValue);
    //Output: Pref changed - Value: true
log(Boolean.toString(((CheckBoxPreference) preference).isChecked()));
    //Output: false
log(String.format("? : %s_%s", preference.getKey(), ((CheckBoxPreference) preference).isChecked()? "checked" : "unchecked"));
    //Output: ? : pref_bfp_navy_unchecked

我的错误在哪里?

4

1 回答 1

7

OnPreferenceChangeListener文档:

返回
True 以使用新值更新 Preference 的状态。

从中可以得出的是,在侦听器返回true之前,首选项的值实际上并没有改变。换句话说,newValue参数 ofonPreferenceChange()是值将是什么,但不是它当前的值(因为您的日志检查在侦听器内部,在返回 true 之前)。

在旁注中,我认为这样做的目的是让您能够拒绝对偏好的无效更改。例如,如果首选项是一个字符串,并且希望它只接受来自某个接受值数组的字符串,则开发人员可以通过返回 false in 来拒绝更改onPreferenceChange()

于 2013-11-07T22:57:07.877 回答