【问题标题】:Listening for Preference change聆听偏好变化
【发布时间】:2016-01-19 21:02:23
【问题描述】:

我正在根据Google tutorial 实施首选项。但是我的事件侦听器没有收到更改。我意识到这是因为我在onResume 中注销了监听器,就像谷歌推荐的那样。我错过了什么还是谷歌的建议有误?

为了在活动中进行适当的生命周期管理,我们建议您 注册和注销您的 SharedPreferences.OnSharedPreferenceChangeListener 期间 onResume() 和 onPause() 分别回调:

public class MyActivity extends AppCompatActivity implements
    NavigationView.OnNavigationItemSelectedListener,
    SharedPreferences.OnSharedPreferenceChangeListener {

public boolean onOptionsItemSelected(MenuItem item) {
        case R.id.action_level: {
            Intent intent = new Intent();
            intent.setClass(this, GamePreferenceActivity.class);
            startActivity(intent);
            return true;
 ...

protected void onPause() {
    Log.d(logTag, "onPause()");
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
    sharedPref.unregisterOnSharedPreferenceChangeListener(this);
    super.onPause();
}

protected void onResume() {
    Log.d(logTag, "onResume()");
    super.onResume();
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
    sharedPref.registerOnSharedPreferenceChangeListener(this);
}

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals(MyPreferenceActivity.KEY_COMPLEXITY)) {
        String value = sharedPreferences.getString(key, "EASY");
        logic.setLevel(Level.valueOf(value));
        restartGame(null);
    }
}

我的活动开始一个带有偏好活动的意图。

public class GamePreferenceActivity extends Activity {
    public static final String KEY_COMPLEXITY = "prefGameComplexity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new GamePreferenceFragment())
                .commit();

        PreferenceManager.setDefaultValues(this, R.xml.game_prefs, false);
    }
}

public class GamePreferenceFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.game_prefs);
    }
}

【问题讨论】:

  • 你能展示你的onResume() 实现吗?文档似乎是正确的。您在onResume() 内注册并在onPause() 内取消注册。
  • 你的问题是什么?
  • 看起来不错。你的监听器实现呢?
  • 当您更改共享首选项时,最后是否调用了 commit()?
  • 不,我没有。谷歌示例中没有这样的代码。感谢您指出这一点。

标签: android android-preferences


【解决方案1】:

您需要致电commit()apply() 以保存对首选项的更改。

示例:

// Access the default SharedPreferences
    SharedPreferences preferences = 
    PreferenceManager.getDefaultSharedPreferences(this);
    // The SharedPreferences editor - must use commit() to submit changes
    SharedPreferences.Editor editor = preferences.edit();

    // Edit the saved preferences
    editor.putString("UserName", "JaneDoe");
    editor.putInt("UserAge", 22);
    editor.commit(); //or editor.apply() -- Read below for difference between these two

commit()apply()的区别:

apply() 是在 2.3 中添加的,它提交时不返回指示成功或失败的布尔值。

commit() 如果保存成功则返回 true,否则返回 false。

apply() 被添加是因为 Android 开发团队注意到几乎没有人注意到返回值,因此 apply 更快,因为它是异步的。

【讨论】:

  • 你能提供完整的源示例吗?我刚刚在一些 SharedPreferences.Editor 类中找到了提交。
  • 很好的解释,我赞成你的工作。但我仍然不明白它与我的用例有何关系。我在序列化更改的数据方面没有问题 - PreferenceFragment 的实现代替了我。我想收到一些更改的通知,所以我实现了 SharedPreferences.OnSharedPreferenceChangeListener 接口。但是永远不会调用侦听器。我怀疑 google 的建议是否正确,因为它在显示 Preference 活动时忘记了侦听器。是我做错了什么还是谷歌教程错了?
  • 我贴了一个完整的代码。我认为我有原因。我希望收到有关偏好已更改(并已完成)的通知,然后修改我的活动。但是我不会在 MyActivity 中监听这个,一旦 GamePreferenceActivity 启动(并且监听器被删除),它就会被暂停。我将在 GamePreferenceActivity 中更新一些共享偏好,表明发生了变化,然后在 MyActivity 中比较这个值。
【解决方案2】:

这是我注册和注销监听器的方式:

@Override
public void onResume() {
super.onResume();
// Register the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
                    .registerOnSharedPreferenceChangeListener(this);
        }

@Override
public void onPause() {
super.onPause();   
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
                        .unregisterOnSharedPreferenceChangeListener(this);
            }

向我们展示你的 onSharedPreferenceChanged,也许你在那里弄错了。

【讨论】:

  • 你在哪里注册这个监听器?在偏好活动或开始偏好活动的那个?
  • 我正在将 OnSharedPreferenceChangeListener 实现为 PreferenceFragment。有 onResume 和 onPause。
  • getPreferenceScreen() 已弃用。有其他选择吗?
  • @Srikar Reddy 阅读这篇文章:stackoverflow.com/questions/14756457/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
  • 2020-10-12
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多