Android: обновление отображаемых настроек из SharedPreferences

Я пишу приложение для Android с параметром preferencesActivity, в котором выбор, сделанный в моем экземпляре preferencesActivity, влияет на значения других отображаемых элементов настроек. Хотя я могу изменять значения базовых элементов SharedPreferences программным способом, эти измененные значения не отражаются в отображаемых элементах списка, пока я не выйду из своего параметра preferencesActivity и не перезагружу его. Ниже представлена ​​урезанная версия моего класса настроек и файла xml, которые иллюстрируют проблему. Если пользователь устанавливает Guitar в качестве значения предпочтения с помощью key instrumentList, я бы хотел, чтобы предпочтение с key tuningChoice вернулось к Standard.

//necessary import declarations go here
public class Settings extends PreferenceActivity implements OnSharedPreferenceChangeListener{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(this);
        app_preferences.registerOnSharedPreferenceChangeListener(this);
    }

    public void  onSharedPreferenceChanged  (SharedPreferences  sharedPreferences, String  key)   {
        Log.d("onSharedPreferencesChanged", "sharedPreferences changed.  key: " + key);
        Editor preferencesMod = sharedPreferences.edit();
        String instrumentChoice = sharedPreferences.getString("instrumentList", "Guitar");
        if(key.equals("instrumentList")) {
            Log.d("Settings", "key is instrumentList.  chooseTuning before if: " +    sharedPreferences.getString("chooseTuning", "no luck"));
            if(instrumentChoice.equals("Guitar")) {
                preferencesMod.putString("chooseTuning", "Standard");
                preferencesMod.commit(); 
                Log.d("Settings", "chooseTuning after if: " +      sharedPreferences.getString("chooseTuning", "ciao"));
            }
        }
    }
}

xml файл preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="Settings">
  <ListPreference android:title="Choose an Instrument" android:key="instrumentList" android:entryValues="@array/instruments" android:entries="@array/instruments"/>
        <ListPreference android:title="Choose Tuning" android:key="chooseTuning" android:entryValues="@array/tuningChoices" android:entries="@array/tuningChoices" android:persistent="true"/>
</PreferenceScreen>

Я могу снова вызвать addPreferencesFromResource в моем методе onSharedPreferenceChanged, который загружает дубликаты всех элементов настроек, отображаемых под старыми элементами, с правильными значениями. Если бы я мог найти способ отменить исходный addPreferencesFromResource, вызываемый во время onCreate, я бы, наверное, установил.

Любая помощь будет оценена, спасибо


person vancan1ty    schedule 13.02.2012    source источник
comment
Посмотрите ответ Джозефа здесь. stackoverflow.com/questions/8003098/   -  person Yefei    schedule 17.04.2012


Ответы (4)


Я делаю что-то в этом роде ... надеюсь, это поможет:

    ListPreference list = (ListPreference) getPreferenceManager().findPreference("myList");
    list.setValue(sharedPrefs.getString("myList", "default"));
    list.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

        public boolean onPreferenceChange(Preference preference, Object newValue) {
            sharedPrefs.put("myList", newValue.toString());
            return true;
        }

    });
person Nick    schedule 13.02.2012
comment
^ Это выглядит многообещающе, спасибо. Один быстрый вопрос: что такое sharedPrefs в этом фрагменте кода? Это экземпляр SharedPreferences? потому что SharedPreferences не имеет метода put ... - person vancan1ty; 13.02.2012
comment
sharedPrefs - это моя собственная оболочка для SharedPreferences. Вы можете просто использовать обычный класс SharedPreferences ... просто убедитесь, что используете commit () там, где это необходимо. - person Nick; 13.02.2012

Вам нужно предотвратить запуск addPReferencesFromResource дважды? Это загружает ваши значения по умолчанию? Если это так, добавьте дополнительный SharedPreference с именем DEFAULTS_LOADED и прочтите его значение при создании, например: (ПРЕДУПРЕЖДЕНИЕ КОД ПСУЭДО):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(this);

    boolean loadDefaults = app_preferences.getBoolean(DEFAULTS_LOADED, true);
    if(loadDefaults)
    {  
        addPreferencesFromResource(R.xml.preferences);
        Editor editor = app_preferences.edit();
        editor.putBoolean(DEFAULTS_LOADED, true);
        editor.commit();
    } 
    app_preferences.registerOnSharedPreferenceChangeListener(this);
}

Это предотвратит запись значений по умолчанию в общие настройки при каждом запуске вашей деятельности. Я предполагаю, что это по крайней мере часть вашей проблемы.

person Nick Campion    schedule 13.02.2012
comment
нет, это не моя проблема. addPreferencesFromResource в настоящее время вызывается только во время onCreate. ЕСЛИ я снова вызываю addPreferencesFromResource после изменения значений sharedPreferences, он загружает повторяющийся набор предпочтений с ПРАВИЛЬНЫМИ значениями ниже старого набора предпочтений с НЕПРАВИЛЬНЫМИ значениями. - person vancan1ty; 13.02.2012
comment
чтобы обойти это, мне нужно либо каким-то образом обновить начальный набор настроек, либо очистить исходный набор и заменить их новым набором с правильными значениями. Я тоже не могу придумать, как это сделать. - person vancan1ty; 13.02.2012
comment
Кроме того, addPreferencesFromResource не загружает значения по умолчанию, а скорее все, что было сохранено при последнем использовании приложения. ^ Тем не менее, спасибо за идею. - person vancan1ty; 13.02.2012
comment
Я не понимаю, как происходит то, что вы делаете. В любом случае, вызов clear в редакторе удалит все существующие свойства в общих ограждениях. - person Nick Campion; 13.02.2012
comment
Я пробовал это. Поведение, которое я получаю, заключается в том, что все базовые элементы sharedPreferences очищаются, НО настройки, отображаемые в пользовательском интерфейсе, остаются неизменными, пока я не выйду из действия и не вернусь. - person vancan1ty; 13.02.2012

Если кто-нибудь придет к этой проблеме, вот решение:

ListView list = preferenceActivity.getListView();
list.performItemClick(list, 1, list.getItemIdAtPosition(1));
person htafoya    schedule 10.04.2012

Может быть, я слишком поздно для ответа на это. Но я надеюсь, что это поможет новичку вроде меня.

PackageInfo packageInfo = null;
try {
    packageInfo = preference.getContext().getPackageManager().getPackageInfo(preference.getContext().getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();   

}
preference.setSummary(packageInfo.versionName);
person Rudy Rudy    schedule 21.11.2018