【问题标题】:Android Preferences: How to load the default values when the user hasn't used the preferences-screen?Android首选项:当用户没有使用首选项屏幕时如何加载默认值?
【发布时间】:2011-02-11 02:47:25
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: android default preferences


    【解决方案1】:

    这个问题和我的类似:

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

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

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

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

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

    【讨论】:

    • 我们可以在我们创建的任何其他 SharedPrefrence 变量上使用它吗?
    • 另外,如果您的应用有多个入口点,请将其放在onCreate() of Application
    • 如果使用布尔值并默认为“false”,这将不起作用,因为在 Android 2.x 中将不会创建默认条目。对“.getBoolean(KEY, true)”的调用将始终返回 true。对于 Android 4.x,它可以工作。
    • readAgain 设置为 true 与覆盖用户首选项无关。来自 Javadoc:注意:这不会将首选项重置为其默认值。
    • 对于那些对此解决方案有问题的人(它不起作用或部分起作用或并非总是起作用)请参阅下面的 Steve Waring 的回答 (stackoverflow.com/a/25602205/4410376)。您很可能有多个共享首选项文件,即 android 正在根据您的配置或杂乱的代码创建多个共享首选项文件。
    【解决方案2】:

    请注意,如果您使用的是
    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);

    我希望这可以帮助某人。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 作为替代方案,您始终可以创建一个仅用于设置默认值的批量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); 一起使用
      • 关于效率:如果你在Application 的子类的onCreate() 中调用它(在清单中注册),它只会在每次应用程序启动时调用一次。对于性能而言,每次应用程序启动时不进行解析(而不是仅在第一次启动时)会更相关(如果有的话),这就是 false 所做的。因此,更多的问题是您是否需要在每次启动时进行检查(例如,何时可能添加新的首选项)或者如果在第一次启动时完成(或重置首选项)是否足够。
      【解决方案4】:

      例如扩展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 时,我需要默认值。
      • 您可以创建自己的类,而不是在 prefs.xml 中使用默认首选项。例如,您可以创建一个从 DialogPreference 扩展的新 DialogPreference 并覆盖 onSetInitialValue。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 2012-09-28
          • 2016-08-14
          • 1970-01-01
          • 1970-01-01
          • 2011-07-31
          • 2013-07-19
          • 1970-01-01
          • 2012-04-24
          • 1970-01-01
          相关资源
          最近更新 更多