【问题标题】:PreferenceManager.setDefaultValues() for several xml preferencesPreferenceManager.setDefaultValues() 用于几个 xml 首选项
【发布时间】:2014-12-18 06:20:51
【问题描述】:

我遇到了与this thread 相同的问题,默认值未针对首选项进行初始化,

我有 2 个preference.xml 文件

这是我主要活动的 onCreate:

protected void onCreate(Bundle savedInstanceState) {
    PreferenceManager.setDefaultValues(this,R.xml.preference,false);
    PreferenceManager.setDefaultValues(this,R.xml.other_preference,false);//this doesn't work now because of the previous row
    String value = PreferenceManager.getDefaultSharedPreferences(this).getString("pref_from_other_preference", null); //this returns null
}

我的问题是,如果我将 readAgain 设置为 false(因此它不会覆盖用户选择的首选项) 仅执行对该方法的第一次调用。

我如何为我所有的偏好 xml 设置默认值?

编辑:我尝试了一个“hack”的解决方案,即尝试获取一个具有默认值的值,如果它为空,则调用getDefaultSharedPreferences 和readAgain 作为true。它没有工作(只有第一次调用初始化了它的值)

【问题讨论】:

    标签: android android-preferences


    【解决方案1】:

    PreferenceManager.setDefaultValues(...) 方法基本上在从指定的 xml 设置 defaultValues 后,将布尔键 KEY_HAS_SET_DEFAULT_VALUES ( = "_has_set_default_values") 存储在一个单独的同名 SharedPreferences 文件中。

    所以这是我的工作 -

    @Override
        protected void onCreate (@Nullable Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setDefaults();
    
        //.......
    }
        private void setDefaults () {
        //This will check if defaults have been set ever before
        if (!getSharedPreferences(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE)
                .getBoolean(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, false)) {
    
            PreferenceManager.setDefaultValues(this, R.xml.preferences, true);
            PreferenceManager.setDefaultValues(this, R.xml.other_preference1, true);
            PreferenceManager.setDefaultValues(this, R.xml.other_preference2, true);
    
        }
    }
    

    在调用此方法之前检查 KEY_HAS_SET_DEFAULT_VALUES 值可确保仅在首次应用启动时调用此方法。 但是正如Héctor Júdez Sapena 所指出的,一旦设置了一个值,这种方法就无效了。因此,始终使用 readAgain = true 调用也不会受到伤害。

    将所有首选项重置为默认值 -

    PreferenceManager.getDefaultSharedPreferences(context).edit().clear().apply();
    PreferenceManager.setDefaultValues(context, R.xml.preferences, true);
    PreferenceManager.setDefaultValues(context, R.xml.other_preference1, true);
    PreferenceManager.setDefaultValues(context, R.xml.other_preference2, true);
    

    或

    PreferenceManager.getDefaultSharedPreferences(context).edit().clear().apply();
    context.getSharedPreferences(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE)
                    .edit()
                    .putBoolean(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, false)
                    .apply();
    //restart application 
    

    请注意,这里我们只处理 Default SharedPreferences 文件。如果您有多个 SharedPreferences 文件,那么您需要为每个文件调用 this。

    【讨论】:

      【解决方案2】:

      我相信这是框架中的某种错误。如果您查看代码,您将看到对PreferenceManager.setDefaultValues 的第一次调用将KEY_HAS_SET_DEFAULT_VALUES 设置为true。在此之后,除非您将 readAgain 设置为 true,否则对 PreferenceManager.setDefaultValues 的任何其他调用都将被忽略。

      这个单一的标志与我们现在需要创建单独的 XML 文件的事实相矛盾,每个设置片段都有一个。并多次调用此方法,就像你正在做的那样。我还没有想出解决方法。因此,目前唯一的解决方案是始终将readAgain 设置为true 进行调用。

      顺便说一句,这是参数readAgain 的唯一用途。一旦存储了设置,即使您将readAgain 设置为true,也无法通过PreferenceManager.setDefaultValues 方法更改该值。如果你想在调用这个方法的时候改变值,那么你需要先清除存储的值。

      【讨论】:

        【解决方案3】:

        您可以在调用 PreferenceManager.setDefaultValues() 方法时删除应重置为默认值的键。所以这些键将使用默认值创建。

        sharedPreferencesEditor= PreferenceManager.getDefaultSharedPreferences(context).edit();
        //this delete myPrefKey key
        sharedPreferencesEditor.remove("myPrefKey").commit();
        
        //this creates keys which didn't exist with defaul values.
        //myPrefKey isn't exist so it will be created
        PreferenceManager.setDefaultValues(this,R.xml.preference,false);
        

        【讨论】:

          【解决方案4】:

          注意docs 这个方法的含义:

          注意:这不会将首选项重置为其默认值。对于该功能,使用 getDefaultSharedPreferences(Context) 并清除它,然后调用此方法并将此参数设置为 true。

          因此,您需要从默认首选项管理器中清除所有首选项才能使用此方法。 重置偏好时我根本不使用这种方法(因为我只需要重置偏好的子集,而不是全部)。相反,我设置了我打算重置为 null 的首选项值。我还使用SharedPreferences.getXXX 方法中的第二个参数来传递默认值,该值在我将首选项设置为null 时可用。

          例如,

          默认资源:

          <bool name="myPrefDefault">true</bool>
          

          偏好:

          <CheckBoxPreference
              android:key="myPrefKey"
              android:title="My Pref Title"
              android:summary="My Pref Summary"
              android:defaultValue="@bool/myPrefDefault" />
          

          Java:

          //this returns whatever preference was set for myPrefKey in PreferencesPage or the default value if nothing was set
          sharedPreferences.getBoolean("myPrefKey", getResources().getBoolean(R.bool.myPrefDefault));
          
          //this effectively resets the myPrefKey to its default value
          sharedPreferences.edit().remove("myPrefKey").commit();
          

          【讨论】:

            猜你喜欢
            • 2019-07-22
            • 2012-05-21
            • 2013-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-24
            • 1970-01-01
            相关资源
            最近更新 更多