Android首选项:当用户没有';你没有使用首选项屏幕吗?

Android首选项:当用户没有';你没有使用首选项屏幕吗?,android,default,preferences,Android,Default,Preferences,我使用PreferenceActivity让用户设置一些值。 我用定义的首选项将xml文件提供给它 我已经为他们设置了所有的android:defaultValue=“ 启动应用程序时,我需要首选项,或者如果尚未手动设置,则需要默认值: SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean value = prefs.getBoolean("key"), false); 然

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

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

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

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean value = prefs.getBoolean("key"), false); 
然而,当android:defaultValue=“true”时,我仍然得到
false
。因此,看起来XML中设置的DefaultValue除了在初始化preferences屏幕时,不会在任何地方使用


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

例如,扩展
对话框首选项
我这样做:

@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中索引的东西

    • 这个问题与我的问题类似:

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

      PreferenceManager.setDefaultValues(this, R.xml.preference, false);
      
      它将从XML加载您的首选项,最后一个参数(
      readreach
      )将保证不会覆盖用户首选项。这意味着将
      readreach
      参数设置为
      false
      意味着只有在以前从未调用过此方法时,才会设置默认值,因此您不必担心每次创建活动时都会覆盖用户的设置


      查看Android API以进行进一步调查。

      请注意,如果您使用的是

      要检索首选项,您必须使用

      设置默认值

      例如:
      PreferenceManager.setDefaultValues(this,PREFS\u NAME,Context.MODE\u PRIVATE,R.xml.preference,false)


      我希望这能帮助某人。

      在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设置为一个高数值。

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

      定义类扩展了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());
          }
      }
      

      好吧,我对你想要达到的目标有点迷茫。我不想调用DialogPreference,当用户不使用首选项时,我需要默认值。您可以创建自己的类,而不是在prefs.xml中使用默认首选项。例如,您可以从DialogPreference扩展创建一个新的DialogPreference并覆盖onSetInitialValue。我们可以将其用于我们创建的任何其他SharedPreference变量吗?此外,如果您的应用程序有多个入口点,请将其放在
      onCreate()中
      应用程序的
      。如果使用布尔值并将默认值设置为“false”,则此项不起作用,因为在Android 2.x中不会创建默认条目。调用“.getBoolean(KEY,true)”将始终返回true。对于Android 4.x来说,它是有效的。将
      readreach
      设置为true与用户偏好被覆盖无关。来自Javadoc:注意:这不会将首选项重置回它们的默认值。对于那些对此解决方案有问题的人(它不起作用、部分起作用或不总是起作用),请参阅下面的Steve Waring的答案()。很可能您有多个共享prefs文件,即android正在根据您的配置或凌乱的代码创建多个共享prefs文件。或者,您可以始终创建一个bulk preferences.xml,仅用于设置默认值。例如,如果您有
      R.xml.prefs_设备
      R.xml.prefs_测试
      ,以及
      R.xml.prefs_管理
      。您可以创建一个prefs文件,其中包含上述所有prefs:
      R.xml.prefs\u用于加载\u默认值
      。然后将其与
      PreferenceManager.setDefaultValues一起使用(这是R.xml.prefs_,用于加载默认值,false)关于效率:如果在
      应用程序
      (注册在清单中)的子类的
      onCreate()
      中调用此函数,则每次应用程序启动都只会调用一次。对于性能而言,最好不要每次启动应用程序时都进行解析(而只是在第一次启动时),这就是
      false
      所做的。因此,问题更多的是您是否需要在每次启动时进行检查(例如,何时可能添加新的首选项),或者如果在第一次启动时进行检查(或重置首选项),是否足够。
      <?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);
      
      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