Android:从SharedPreferences更新显示的首选项

时间:2012-02-13 14:57:52

标签: android preferences sharedpreferences

我正在编写一个带有preferencesActivity的Android应用程序,其中在我的preferencesActivity实例中进行的选择会影响显示的其他首选项的值。虽然我能够以编程方式更改底层SharedPreferences项的值,但在退出我的preferencesActivity并重新加载之前,这些更改的值不会反映在显示的列表项中。下面是我的设置类和xml文件的精简版本,用于说明问题。如果用户使用关键instrumentList将Guitar设置为首选项的值,我希望将关键字tuneChoice的首选项恢复为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>

我可以在我的onSharedPreferenceChanged方法中再次调用addPreferencesFromResource,并使用正确的值加载显示在旧项目下方的所有首选项项目的副本。如果我能找到一些方法来取消在onCreate期间调用的初始addPreferencesFromResource,我猜我会被设置。

任何帮助将不胜感激,谢谢

4 个答案:

答案 0 :(得分:1)

我在这些方面做了些什么......希望它有所帮助:

    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;
        }

    });

答案 1 :(得分:0)

您需要阻止addPReferencesFromResource运行两次吗?这是加载您的默认值吗?如果是这样,添加一个名为DEFAULTS_LOADED的额外SharedPreference,并在创建时读取其值,如:(警告PSUEDO代码):

@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);
}

这将阻止您在每次活动开始时将默认值写入共享首选项。我认为这至少是你问题的一部分。

答案 2 :(得分:0)

如果有人遇到这个问题,这就是解决方案:

ListView list = preferenceActivity.getListView();
list.performItemClick(list, 1, list.getItemIdAtPosition(1));

答案 3 :(得分:0)

也许我为时已晚。但是,我希望这会对像我这样的初学者有所帮助。

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

}
preference.setSummary(packageInfo.versionName);