16

我正在尝试使用 AndroidPreferenceScreen作为一种方便的方式来布局我的用户设置,但我不想将首选项保存到设备共享首选项中。这是可能的,还是我应该使用不同的机制,例如ListView

使用该PreferenceScreen类型似乎真的很方便,因为我需要不同的小部件(即开关、编辑文本)。但是我已经遇到了持久性问题,即。即使在我不希望的会话中,我输入的任何内容也会持续存在。

设置.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Preference
        android:key="settings_type"
        android:title="@string/label_type" />

    <EditTextPreference
        android:key="settings_edit_name"
        android:title="@string/label_name"
        android:dialogTitle="Enter a name"
        android:singleLine="true" />

    <SwitchPreference
        android:key="settings_edit_state"
        android:title="@string/label_state"
        android:summary="Enable or disable the state" />

</PreferenceScreen>
4

5 回答 5

18

我知道这是一个老问题,但我觉得它很有趣。只需将此属性设置为您的偏好,它将不会被保存:

android:persistent="false"
于 2013-09-23T08:36:55.467 回答
6

我重新阅读了相应的文档并确定了如何通过实现Preference.OnPreferenceChangeListener接口来防止保存首选项。

公共静态接口 Preference.OnPreferenceChangeListener

当此 Preference 的值已被用户更改并且即将设置和/或持久化时要调用的回调的接口定义。这使客户端有机会阻止设置和/或保留该值。

例子:

public class SettingsFragment extends PreferenceFragment {

    public static SettingsFragment newInstance(int index) {
        SettingsFragment f = new SettingsFragment();

        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);

        return f;
    }

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

        addPreferencesFromResource(R.layout.settings);

        // getArguments().getInt("index");

        EditTextPreference namePreference = (EditTextPreference) findPreference("settings_edit_name");
        namePreference.setOnPreferenceChangeListener(new NamePreferenceChangeListener());

    }

    private class NamePreferenceChangeListener implements Preference.OnPreferenceChangeListener {

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        // Do something else presumably and then return false to avoid saving the pref.
        return false;
    }

}
于 2013-01-31T20:11:36.740 回答
1

您可以只使用线性布局并在其中放置所需组件的非首选版本。

于 2013-01-31T19:22:26.383 回答
0

由于首选项必然会被存储,因此您始终可以在 onCreate 中清除它们

在 PreferenceFragment 的 onCreate 中试试这个

super.onCreate();
getPreferenceManager().setSharedPreferencesName("custom");
SharedPreferences sp = getPreferenceManager().getSharedPreferences();
SharedPreferences.Editor editor = sp.edit();
editor.clear();
editor.apply();
于 2013-01-31T19:41:03.290 回答
0

我建议创建一个子类PreferenceDataStore并将其分配给您的PreferenceManager.

偏好数据存储

要实现并提供给 Preference 框架的数据存储接口。如果需要,这可用于替换默认的 android.content.SharedPreferences。

偏好管理器

public void setPreferenceDataStore (PreferenceDataStore dataStore)

设置一个 PreferenceDataStore 供与此管理器关联的所有首选项使用,这些首选项没有通过 分配的自定义 PreferenceDataStore Preference.setPreferenceDataStore(PreferenceDataStore)。此外,如果设置了数据存储,则只要将子首选项分配给此管理器,它们就不会使用 SharedPreferences。

例子

自定义数据存储

    class CustomDataStore: PreferenceDataStore() {
    override fun putBoolean(key: String?, value: Boolean) {
        when (key) {
            knownKey -> // Do something
            anotherKnownKey -> // Do somthing else
        }
    }

    override fun putString(key: String?, value: String?) {
        when (key) {
            knownKey -> // Do something
            anotherKnownKey -> // Do something else
        }
    }

    // You can ignore unused types but make sure to still override to avoid UnsupportedOperationException
    override fun putFloat(key: String?, value: Float) {}
    override fun putInt(key: String?, value: Int) {}
    override fun putLong(key: String?, value: Long) {}
    override fun putStringSet(key: String?, values: MutableSet<String>?) {}

    override fun getBoolean(key: String?, defValue: Boolean): Boolean {
        return when (key) {
            knownKey -> // Do something
            anotherKnownKey -> // Do something else
            else -> defValue
        }
    }

    override fun getString(key: String?, defValue: String?): String? {
        return when (key) {
            knownKey -> // Do something
            anotherKnownKey -> // Do something else
            else -> defValue
        }
    }
}

注意:子类化时要小心,因为所有抽象put()方法都会抛出UnsupportedOperationException.

PreferenceFragment 或 PreferenceFragmentCompat

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    // Prevent saving to SharedPreferences, use a custom data store
    preferenceManager.preferenceDataStore = CustomDataStore()
}
于 2020-11-24T03:00:41.803 回答