简体   繁体   中英

SharedPreferences.OnSharedPreferenceChangeListener not called when ListPreference changes value

I opened a plain project in order to simplify testing out an issue that I can't solve - why is my listener not called when the user changes the value of a ListPreference . The values are changed, as can be seen by rerunning the app.

The preferences.xml is simple:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <ListPreference
        android:title="list preference"
        android:key="@string/pref_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:persistent="true"
        android:entryValues="@array/all_blah"
        android:entries="@array/all_blah"
        android:summary="%s" />

</PreferenceScreen>

It refers to the following entries in my strings.xml

<string-array name="all_blah">
    <item>blah 1</item>
    <item>blah 2</item>
    <item>blah 3</item>
    <item>blah 4</item>
</string-array>
<string name="pref_list">pref_list</string>
<string name="pref_file">SharedPrefFile</string>

The MainActivity is fairly simple:

package com.acme.settingstest;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent modifySettings=new Intent(MainActivity.this, SettingsActivity.class);
                startActivity(modifySettings);
            }
        });
    }
}

And last, the SettingsActivity which is:

package com.acme.settingstest;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

class SettingsActivity extends AppCompatActivity {

    SharedPreferences mPrefs = null;
    private static final String TAG = "SettingsActivity";

    private final SharedPreferences.OnSharedPreferenceChangeListener mListener =
            new SharedPreferences.OnSharedPreferenceChangeListener() {
                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
                    if (key.equals(getString(R.string.pref_list))) {
                        Log.e(TAG, "caught change in pref_list");
                    }
                }

            };

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

        mPrefs = getSharedPreferences(getString(R.string.pref_file), Context.MODE_PRIVATE);
        getFragmentManager()
                .beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
    }

    @Override
    public void onPause() {
        super.onPause();
        mPrefs.unregisterOnSharedPreferenceChangeListener(mListener);
    }

    @Override
    public void onResume() {
        super.onResume();
        mPrefs.registerOnSharedPreferenceChangeListener(mListener);
    }

    public static class SettingsFragment extends PreferenceFragment {

        @Override
        public void onCreate(@Nullable final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
        }
    }
}

You are using a non-default preferences in SettingsActivity but you aren't indicating the PreferenceManager which shared preference should use.

The OnSharedPreferenceChangeListener is registered to the SharedPreferences - SharedPrefFile - which is not the default one.

In the SettingsFragment in the OnCreate before adding the preferences try setting the SharedPreferencesName. Something like this:

 PreferenceManager prefMgr = getPreferenceManager();
 prefMgr.setSharedPreferencesName(getString(R.string.pref_file));
 prefMgr.setSharedPreferencesMode(MODE_WORLD_READABLE);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM