【问题标题】:Android: updating displayed preferences from SharedPreferencesAndroid:从 SharedPreferences 更新显示的首选项
【发布时间】:2012-03-04 23:27:48
【问题描述】:

我正在编写一个带有preferencesActivity 的android 应用程序,其中在我的preferencesActivity 实例中所做的选择会影响显示的其他首选项项目的值。虽然我能够以编程方式更改底层 SharedPreferences 项的值,但这些更改的值不会反映在显示的列表项中,直到我退出我的 preferencesActivity 并重新加载它。下面是我的设置类和 xml 文件的精简版本,它说明了问题。如果用户使用键 instrumentList 将 Guitar 设置为首选项的值,我希望使用键 tuneChoice 的首选项恢复为标准。

//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,我想我会被设置。

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

【问题讨论】:

标签: android preferences sharedpreferences


【解决方案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;
        }

    });

【讨论】:

  • ^这看起来很有希望,谢谢。一个快速的问题:这段代码 sn-p 中的 sharedPrefs 是什么?它是 SharedPreferences 的一个实例吗?因为 SharedPreferences 没有 put 方法...
  • sharedPrefs 是我自己的 SharedPreferences 自定义包装器。您可以只使用普通的 SharedPreferences 类...只要确保在必要时使用 commit()。
【解决方案2】:

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

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

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

【讨论】:

  • 不,这不是我的问题。 addPreferencesFromResource 目前仅在 onCreate 期间被调用。如果我在更改 sharedPreferences 值后再次调用 addPreferencesFromResource ,它会加载一组重复的首选项,其中 CORRECT 值低于旧的首选项集和 INCORRECT 值。
  • 为了解决这个问题,我要么需要以某种方式更新初始首选项集,要么清除初始集并将其替换为具有正确值的新集。我也想不出办法。
  • 另外,addPreferencesFromResource 不加载“默认”值,而是加载上次使用应用程序时保存的任何内容。 ^谢谢你的想法。
  • 我对你正在做的事情感到困惑。无论如何,在编辑器上调用 clear 将删除共享参数中的所有现有属性。
  • 我试过了。我得到的行为是,底层的 sharedPreferences 项目确实都被清除了,但是 UI 中显示的首选项保持不变,直到我离开活动并回来。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    也许我回答这个问题已经太晚了。但是,我希望这可以帮助像我这样的初学者。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多