Android首选项:如何在用户未使用首选项屏幕时加载默认值?

时间:2010-04-22 14:40:14

标签: android default preferences

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

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

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

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

然而,当android:defaultValue="true"我仍然得到false时。因此,看起来XML中设置的defaultValues不会在初始化首选项屏幕时使用。

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

6 个答案:

答案 0 :(得分:161)

这个问题与我的相似:

initialize-preferences-from-xml-in-main-activity

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

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

它将从XML加载您的首选项,最后一个参数(readAgain)将保证不会覆盖用户首选项。

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

答案 1 :(得分: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);

我希望这可以帮助别人。

答案 2 :(得分:12)

在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设置为高数字。

答案 3 :(得分: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中编入索引的内容。

答案 4 :(得分:0)

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

答案 5 :(得分: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