Настройки Android: Как загрузить значения по умолчанию, когда пользователь не использовал экран настроек?

Я использую PreferenceActivity, чтобы позволить пользователю установить некоторые значения. Я кормить его XML-файл с определенными предпочтениями.

Я установил все android:defaultValue="" для них.

Когда я запускаю свое приложение, мне нужны настройки, или, если они еще не установлены вручную, мне нужны значения по умолчанию:

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

Однако когда android:defaultValue="true" Я все еще получаю false, Таким образом, похоже, что defaultValues, установленные в XML, нигде не используются, но при инициализации экрана настроек.

Я не хочу жестко задавать значения по умолчанию в getBoolean() метод. Итак, есть ли способ получить значения по умолчанию, определяя их только в 1 месте?

5 ответов

Решение

Этот вопрос похож на мой:

инициализирует-предпочтения-из-XML-в-основной-деятельности

Просто используйте этот код в onCreate метод:

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

Он загрузит ваши настройки из XML и последний параметр (readAgain) гарантирует, что пользовательские настройки не будут перезаписаны.

Загляните в PreferenceManager.setDefaultValues в Android API для дальнейшего изучения.

Имейте в виду, что если вы используете
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);

Я надеюсь, что это может кому-то помочь.

В принятом ответе 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 на высокое число.

Например расширение 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.

Также убедитесь, что вы никогда не использовали SharedPreferences раньше. Чтобы убедиться, что они не изменены (что означает, что setDefaultValues ​​(this,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());
    }
}

определить предпочтительный ресурс 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
Другие вопросы по тегам