2

我有一个PreferenceFragment用于更改几个不同项目的相同设置。显然,不同的项目需要使用不同的键存储偏好值。所以我在创建片段后更改了所有首选项的键。

首选项通常由 xml 定义:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="_key_one"
        android:title="Title of first preference" />
    [... and more Preferences]
</PreferenceScreen>

我更改键的 PreferenceFragment :

public class ItemSettingPreferenceFragment extends PreferenceFragment {

    private String mItemKey;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mItemKey = getArguments().getString('item_key');     //this will contain name of item
        addPreferencesFromResource(R.xml.item_settings_preferences);
        for (int i=0; i< getPreferenceScreen().getPreferenceCount(); i++){
            final Preference pref = getPreferenceScreen().getPreference(i);
            pref.setKey(mItemKey + pref.getKey());
        }
    }
}

现在所有首选项对每个项目都有一个唯一的键,例如“item1_key_one”
不幸的是,这些首选项在创建后会加载并显示带有原始键“_key_one”的值

如何强制首选项重新加载新键的值并显示它们?

4

3 回答 3

4

据我所知,“key”就像您偏好的“id”,这意味着您无法在创建偏好“key”后更改它。如果您需要动态生成首选项,那么您可能不应该在 XML 中定义您的首选项。

这是来自 android 示例 API 的示例,它演示了如何从代码而不是 XML 生成首选项。

public class PreferencesFromCode extends PreferenceActivity {

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

    setPreferenceScreen(createPreferenceHierarchy());
}

private PreferenceScreen createPreferenceHierarchy() {
    // Root
    PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);

    // Inline preferences
    PreferenceCategory inlinePrefCat = new PreferenceCategory(this);
    inlinePrefCat.setTitle(R.string.inline_preferences);
    root.addPreference(inlinePrefCat);

    // Checkbox preference
    CheckBoxPreference checkboxPref = new CheckBoxPreference(this);
    checkboxPref.setKey("checkbox_preference");
    checkboxPref.setTitle(R.string.title_checkbox_preference);
    checkboxPref.setSummary(R.string.summary_checkbox_preference);
    inlinePrefCat.addPreference(checkboxPref);

    // Switch preference
    SwitchPreference switchPref = new SwitchPreference(this);
    switchPref.setKey("switch_preference");
    switchPref.setTitle(R.string.title_switch_preference);
    switchPref.setSummary(R.string.summary_switch_preference);
    inlinePrefCat.addPreference(switchPref);

    // Dialog based preferences
    PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this);
    dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences);
    root.addPreference(dialogBasedPrefCat);

    // Edit text preference
    EditTextPreference editTextPref = new EditTextPreference(this);
    editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference);
    editTextPref.setKey("edittext_preference");
    editTextPref.setTitle(R.string.title_edittext_preference);
    editTextPref.setSummary(R.string.summary_edittext_preference);
    dialogBasedPrefCat.addPreference(editTextPref);

    // List preference
    ListPreference listPref = new ListPreference(this);
    listPref.setEntries(R.array.entries_list_preference);
    listPref.setEntryValues(R.array.entryvalues_list_preference);
    listPref.setDialogTitle(R.string.dialog_title_list_preference);
    listPref.setKey("list_preference");
    listPref.setTitle(R.string.title_list_preference);
    listPref.setSummary(R.string.summary_list_preference);
    dialogBasedPrefCat.addPreference(listPref);

    // Launch preferences
    PreferenceCategory launchPrefCat = new PreferenceCategory(this);
    launchPrefCat.setTitle(R.string.launch_preferences);
    root.addPreference(launchPrefCat);

    /*
     * The Preferences screenPref serves as a screen break (similar to page
     * break in word processing). Like for other preference types, we assign
     * a key here so that it is able to save and restore its instance state.
     */
    // Screen preference
    PreferenceScreen screenPref = getPreferenceManager().createPreferenceScreen(this);
    screenPref.setKey("screen_preference");
    screenPref.setTitle(R.string.title_screen_preference);
    screenPref.setSummary(R.string.summary_screen_preference);
    launchPrefCat.addPreference(screenPref);

    /*
     * You can add more preferences to screenPref that will be shown on the
     * next screen.
     */

    // Example of next screen toggle preference
    CheckBoxPreference nextScreenCheckBoxPref = new CheckBoxPreference(this);
    nextScreenCheckBoxPref.setKey("next_screen_toggle_preference");
    nextScreenCheckBoxPref.setTitle(R.string.title_next_screen_toggle_preference);
    nextScreenCheckBoxPref.setSummary(R.string.summary_next_screen_toggle_preference);
    screenPref.addPreference(nextScreenCheckBoxPref);

    // Intent preference
    PreferenceScreen intentPref = getPreferenceManager().createPreferenceScreen(this);
    intentPref.setIntent(new Intent().setAction(Intent.ACTION_VIEW)
            .setData(Uri.parse("http://www.android.com")));
    intentPref.setTitle(R.string.title_intent_preference);
    intentPref.setSummary(R.string.summary_intent_preference);
    launchPrefCat.addPreference(intentPref);

    // Preference attributes
    PreferenceCategory prefAttrsCat = new PreferenceCategory(this);
    prefAttrsCat.setTitle(R.string.preference_attributes);
    root.addPreference(prefAttrsCat);

    // Visual parent toggle preference
    CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this);
    parentCheckBoxPref.setTitle(R.string.title_parent_preference);
    parentCheckBoxPref.setSummary(R.string.summary_parent_preference);
    prefAttrsCat.addPreference(parentCheckBoxPref);

    // Visual child toggle preference
    // See res/values/attrs.xml for the <declare-styleable> that defines
    // TogglePrefAttrs.
    TypedArray a = obtainStyledAttributes(R.styleable.TogglePrefAttrs);
    CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this);
    childCheckBoxPref.setTitle(R.string.title_child_preference);
    childCheckBoxPref.setSummary(R.string.summary_child_preference);
    childCheckBoxPref.setLayoutResource(
            a.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild,
                    0));
    prefAttrsCat.addPreference(childCheckBoxPref);
    a.recycle();

    return root;
}

}

在这里,您将能够在创建首选项之前setKey()

于 2013-07-14T20:32:02.177 回答
2

在阅读了所有相关的 Preference 类之后,我找到了一个简单的解决方案。由于没有允许重新加载首选项的公共方法,我必须使用反射。
我必须调用的必要方法可以protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue)在任何子类中找到Preference.class或被任何子类覆盖。
因为我不知道哪个超类实现了这个方法,所以我必须遍历所有超类并尝试找到并调用该方法,直到成功。

public class ItemSettingPreferenceFragment extends PreferenceFragment {

    private String mItemKey;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mItemKey = getArguments().getString('item_key');     //this will contain name of item
        addPreferencesFromResource(R.xml.item_settings_preferences);
        for (int i=0; i< getPreferenceScreen().getPreferenceCount(); i++){
            Preference pref = getPreferenceScreen().getPreference(i);
            pref.setKey(mItemKey + pref.getKey());

            Class iterClass = pref.getClass();
            while(iterClass != Object.class) {
                try {
                    Method m = iterClass.getDeclaredMethod("onSetInitialValue", boolean.class, Object.class);
                    m.setAccessible(true);
                    m.invoke(pref, true, null);
                } catch (Exception e) { }
                iterClass = iterClass.getSuperclass();
            }
        }
    }
}

它可能不是最高效的解决方案,但它适用于我的情况。

于 2013-07-15T23:06:25.910 回答
0

最简单的解决方案是使用单独的设置名称:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getPreferenceManager().setSharedPreferencesName("MyPrefs_" + someSufix);
    addPreferencesFromResource(R.xml.pref_my);
}

而不是为键值添加前缀。

于 2015-02-05T21:16:56.997 回答