128

我正在使用 PreferenceActivity 让用户设置一些值。我正在用定义的首选项向它提供 xml 文件。

我已经android:defaultValue=""为他们设置了所有。

当我启动我的应用程序时,我需要首选项,或者如果尚未手动设置它们,我需要默认值:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean value = prefs.getBoolean("key"), false); 

但是,当android:defaultValue="true"我仍然得到false. 因此,看起来 XML 中设置的 defaultValues 没有在任何地方使用,而是在初始化首选项屏幕时使用。

我不想硬编码getBoolean()方法中的默认值。那么,有没有办法只在一个地方定义这些默认值?

4

6 回答 6

184

这个问题和我的类似:

初始化首选项-来自-xml-in-main-activity

只需在onCreate方法中使用此代码:

PreferenceManager.setDefaultValues(this, R.xml.preference, false);

它将从 XML 加载您的首选项,最后一个参数 ( readAgain) 将保证用户首选项不会被覆盖。这意味着将readAgain参数设置为false意味着仅在过去从未调用过此方法时才设置默认值,因此您不必担心每次创建 Activity 时都会覆盖用户的设置

查看Android API 中的PreferenceManager.setDefaultValues以进行进一步调查。

于 2010-05-20T21:00:24.350 回答
27

请注意,如果您正在使用
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

检索您必须用来 设置默认值的首选项!
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

例如:
PreferenceManager.setDefaultValues(this, PREFS_NAME, Context.MODE_PRIVATE, R.xml.preference, false);

我希望这可以帮助某人。

于 2011-12-19T18:58:55.863 回答
13

在 Pixel 接受的答案中:

PreferenceManager.setDefaultValues(this, R.xml.preference, false);

据说这false意味着默认值不会被覆盖。这不是它的作用,它只是一个效率标志,如果您的应用程序有多个入口点,则停止解析。不幸的是,测试不是针对每个首选项文件进行的,因此如果您有多个首选项文件,则必须对除true第一个文件之外的所有文件进行编码。

如果你担心效率,你可以编写这样的代码。

final static private int SPL = 1;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (sp.getInt("spl", 0) != SPL)
{
    PreferenceManager.setDefaultValues(this, R.xml.prefs1, true);
    PreferenceManager.setDefaultValues(this, R.xml.prefs2, true);
    sp.edit().putInt("spl", SPL).apply();
}

如果您添加了更多共享首选项,只需将 SPL 设置为一个高数。

于 2014-09-01T08:57:08.480 回答
2

例如扩展DialogPreference我这样做:

@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
    super.onSetInitialValue(restore, defaultValue);

    if (restore) {
        mValue = shouldPersist() ? getPersistedString(mDefault) : mDefault;
    } else {
        mValue = mDefault;
    }
}

mDefault 可以是:

  • mContext.getResources().getString(attrs.getAttributeResourceValue(androidns,"defaultValue", 100));
  • 你在 R 中索引的东西。
于 2010-04-22T14:59:44.257 回答
1

还要确保您以前从未使用过 SharedPreferences。为确保它们没有被更改(这意味着 setDefaultValues(this,xml,false) 无效)卸载您的应用程序并再次上传以确保未触及任何值。这对我有帮助。

于 2016-11-30T15:36:02.250 回答
0

定义类扩展 android.preference.Preference

public class IntegerPreference extends Preference {
    public IntegerPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public IntegerPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public IntegerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public IntegerPreference(Context context) {
        super(context);
    }

    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
        super.onSetInitialValue(restorePersistedValue, defaultValue);
        persistInt((Integer) defaultValue);
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        return a.getInt(index, -1);
    }
}

public class StringSetPreference extends Preference {
    public StringSetPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public StringSetPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public StringSetPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public StringSetPreference(Context context) {
        super(context);
    }

    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
        super.onSetInitialValue(restorePersistedValue, defaultValue);
        persistStringSet((Set<String>) defaultValue);
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        return Stream.of(a.getTextArray(index)).map(String::valueOf).collect(Collectors.toSet());
    }
}

定义偏好 XML 资源

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.ainirobot.preferencetest.IntegerPreference
        android:defaultValue="101"
        android:key="III" />
    <com.ainirobot.preferencetest.FloatPreference
        android:defaultValue="1.2"
        android:key="FFF" />
    <com.ainirobot.preferencetest.StringPreference
        android:defaultValue="SSS"
        android:key="SSS" />
    <com.ainirobot.preferencetest.BooleanPreference
        android:defaultValue="True"
        android:key="BBB" />
    <com.ainirobot.preferencetest.StringSetPreference
        android:defaultValue="@array/sset"
        android:key="SSET" />
</PreferenceScreen>

然后初始化默认值并访问

    PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

    Map<String, ?> allKeys = PreferenceManager.getDefaultSharedPreferences(this).getAll();
    int iii = PreferenceManager.getDefaultSharedPreferences(this).getInt("III", -1);
    float fff = PreferenceManager.getDefaultSharedPreferences(this).getFloat("FFF", 0);
    Log.d(TAG, "allKeys=" + allKeys + " iii=" + iii + " fff=" + fff);

//Logcat

10-13 06:53:06.986 12594 12594 D MainActivity: allKeys={III=101, BBB=true, SSS=SSS, FFF=1.2, SSET=[XXX, ZZZ, YYY]} iii=101 fff=1.2
于 2020-10-13T06:58:19.057 回答