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

发布于 2024-08-29 12:07:13 字数 540 浏览 6 评论 0原文

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

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

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

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

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

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

I am using a PreferenceActivity to let the user set some values.
I am feeding it the xml file with the defined preferences.

I have set all the android:defaultValue="" for them.

When I start my application, I need the preferences, or if they are not set yet manually, I want the default values:

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

However, when android:defaultValue="true" I still get false. So, it looks like the defaultValues set in the XML are not used anywhere but when initializing the preferences-screen.

I don't want to hardcode the default values in the getBoolean() method. So, is there a way get the default-values with only defining these in 1 place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

复古式 2024-09-05 12:07:13

这个问题与我的类似:

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

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

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

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

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

this question is similar to mine:

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

Just use this code in onCreate method:

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

It will load your preferences from XML, and last parameter (readAgain) will guarantee that user preferences won't be overwritten. That means setting the readAgain argument to false means this will only set the default values if this method has never been called in the past so you don't need to worry about overriding the user's settings each time your Activity is created

Take a look into PreferenceManager.setDefaultValues in Android API for further investigation.

青朷 2024-09-05 12:07:13

请注意,如果您正在使用
getSharedPreferences(字符串sharedPreferencesName,int共享PreferencesMode)

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

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

我希望这可以帮助别人。

Be aware that if you are using
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

to retrieve preferences you have to use
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)
to set defaults!

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

I hope this can help someone.

我为君王 2024-09-05 12:07: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 设置为较高的数字即可。

in Pixel's accepted answer:

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

it is stated that the false means that defaults won't be overwritten. This is not what it does, it is just an efficiency flag to stop the parsing if your application has more than one entry point. Unfortunately the test is not made per preference file, so if you have more than one preference file you must code true on all but the first.

If you are worried about efficiency, you could code something like this.

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

If you ever add more shared preferences, just set SPL to a hight number.

超可爱的懒熊 2024-09-05 12:07:13

例如扩展 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 中索引的东西。

For example extending DialogPreference I do this:

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

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

mDefault can be:

  • mContext.getResources().getString(attrs.getAttributeResourceValue(androidns,"defaultValue", 100));
  • something you have indexed in R.
呆橘 2024-09-05 12:07:13

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

Also make sure you have never used the SharedPreferences before. To make sure they are not changed (which means setDefaultValues(this,xml,false) has no effect) uninstall your App and upload it again to be sure no values are touched. This helped me.

生生不灭 2024-09-05 12:07:13

定义类扩展 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

define class extends 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());
    }
}

define preference XML resource

<?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>

then initialize default value and access

    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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文