Android偏好设置:当用户未使用偏好设置屏幕时,如何加载默认值?


119

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

我已经android:defaultValue=""为他们准备好了。

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

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

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

我不想在getBoolean()方法中对默认值进行硬编码。因此,有没有办法仅在1个地方定义默认值?

Answers:


169

这个问题类似于我的:

从主要活动中的xml初始化偏好

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

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

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

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


我们可以在创建的任何其他SharedPrefrence变量上使用它吗?
Amol Gupta

8
另外,如果您的应用有多个入口点,请将其放在onCreate()Application
SD

2
如果使用布尔值并将其默认设置为“ false”,则此方法将不起作用,因为这样将不会在Android 2.x中创建默认条目。调用“ .getBoolean(KEY,true)”将始终返回true。适用于Android4.x。
Gunnar Bernstein 2013年

10
设置readAgain为true与覆盖用户首选项无关。在Javadoc中:注意:这不会将首选项恢复为默认值。
devconsole 2014年

1
对于对此解决方案有疑问的人(该解决方案不起作用或部分起作用或不总是起作用),请参阅下面的史蒂夫·沃林的答案(stackoverflow.com/a/25602205/4410376)。您最有可能拥有多个共享偏好文件,即android基于您的配置或凌乱的代码创建了多个共享偏好文件。
Hack06年

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);

我希望这可以帮助某人。


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设置为较高的数字即可。


2
或者,您始终可以创建仅用于设置默认值的批量preferences.xml。举例来说,如果你有 R.xml.prefs_deviceR.xml.prefs_testR.xml.prefs_admin。您可以创建一个包含上述所有偏好设置的偏好设置文件 R.xml.prefs_for_loading_default_values。然后将其与 PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo

关于效率:如果在(在清单中注册的)onCreate()子类中调用此方法,Application则无论如何每个应用程序启动都只会调用一次。为了提高性能,在每次启动应用程序时(而不是仅在首次启动时)不进行解析会更相关(如果有的话),这就是这样false做的原因。因此,更多的问题是您是否需要在每次启动时进行检查(例如,何时添加新的首选项),或者是否在第一次启动时进行检查(或者重置首选项)是否足够。
user905686

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中建立索引的内容。

好的,我对您要达到的目标有些困惑。我不想调用DialogPreference,当用户不使用Preferences时,我需要默认值。
Peterdk 2010年

您可以创建自己的类,而不是在prefs.xml中使用默认的Preferences。例如,您可以创建一个从DialogPreference扩展的新DialogPreference并覆盖onSetInitialValue。
Macarse

0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.