How to listen for preference changes within a PreferenceFragment?

前端 未结 9 2042
自闭症患者
自闭症患者 2020-11-28 19:16

As described here, I am subclassing PreferenceFragment and displaying it inside an Activity. That document explains how to listen for preference changes here, but only if yo

相关标签:
9条回答
  • 2020-11-28 19:30

    This worked for me from PreferenceFragment.onCreate()

    OnSharedPreferenceChangeListener listener = 
        new SharedPreferences.OnSharedPreferenceChangeListener()
        {
            public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
            {
             showDialog();
            }
        };
    
    0 讨论(0)
  • 2020-11-28 19:38

    I recently finished putting together my own PreferenceScreen using the Preferences API, so I thought I would contribute my own full Example.. This includes updating the Summary to new/changed Value, as well as Listening for and reacting to changes.

    PS. To answer your last question: To show a default Value for Summary upon initial creation of the PreferenceScreen (prior to any change in the Value), you could simply set the android:summary to a Value of your choosing, from within the preferences.xml file directly - and then, once there is a change in the Value, it will update automatically by using the code contained in my Example below. Personally, I use a short explanation of the Preference as my initial Summary, set within my preferences.xml, and then once the Value does get changed for the first time, it will simply show the current Value as the Summary from then on..

    Anyhow, here is my full Example:

    SettingsFragment.java

    public class SettingsFragment extends PreferenceFragment {
    
    public static final String PREF_NOTIFICATION_MODE = "pref_notificationMode";
    private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
    
    @Override
    public void onCreate (@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    
        final SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity());
    
        preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    
                if (key.equals(PREF_NOTIFICATION_MODE)) {
                    Preference notifModePref = findPreference(key);
                    notifModePref.setSummary(sharedPreferences.getString(key, ""));
    
                    //  DO SOMETHING ELSE HERE WHEN (PREF_NOTIFICATION_MODE) IS CHANGED
                }
            }
        };
    }
    
    @Override
    public void onResume() {
        super.onResume();
    
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(preferenceChangeListener);
    
        Preference notifModePref = findPreference(PREF_NOTIFICATION_MODE);
        notifModePref.setSummary(getPreferenceScreen().getSharedPreferences().getString(PREF_NOTIFICATION_MODE, ""));
    
    }
    
    @Override
    public void onPause() {
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
    
        super.onPause();
    }
    }
    


    I hope this helps!
    Any positive feedback is greatly appreciated, as I'm fairly new to StackOverflow ;)
    Happy coding!

    0 讨论(0)
  • 2020-11-28 19:39

    The solution of antew works well, here you can see a full preference activity for Android v11 onwards:

    import android.app.Activity;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
    import android.os.Bundle;
    import android.preference.ListPreference;
    import android.preference.PreferenceFragment;
    
    public class UserPreferencesV11 extends Activity  {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Display the fragment as the main content.
        getFragmentManager().beginTransaction().replace(android.R.id.content,
                new PrefsFragment()).commit();
    }
    
    public static class PrefsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.preferences);
    
            // set texts correctly
            onSharedPreferenceChanged(null, "");
    
        }
    
        @Override
        public void onResume() {
            super.onResume();
            // Set up a listener whenever a key changes
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
        }
    
        @Override
        public void onPause() {
            super.onPause();
            // Set up a listener whenever a key changes
            getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
        }
    
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            // just update all
            ListPreference lp = (ListPreference) findPreference(PREF_YOUR_KEY);
            lp.setSummary("dummy"); // required or will not update
            lp.setSummary(getString(R.string.pref_yourKey) + ": %s");
    
        }
    }
    }
    
    0 讨论(0)
  • 2020-11-28 19:39

    You just need to delare the specified Prefernce class in your onResume() method. In my case I was using SwitchPreference class, therefore the code would be like- SettingsActivity.class

    public static class PrivacyPreferenceFragment extends PreferenceFragment
    {
        public SwitchPreference switchPreference;
    
        @Override
        public void onResume() {
            super.onResume();
            switchPreference = (SwitchPreference) findPreference("privacy_notice_check");
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_privacy);
            setHasOptionsMenu(true);
    
        }
    

    Then in the activity where you want to use the PrefernceFragment value, just use the SharedPreference object to call the values and trigger it.

    0 讨论(0)
  • 2020-11-28 19:40

    I believe you just need to register/unregister the Listener in your PreferenceFragment and it will work.

    @Override
    public void onResume() {
        super.onResume();
        getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    
    }
    
    @Override
    public void onPause() {
        getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
        super.onPause();
    }
    

    Depending on what you want to do you may not need to use a listener. Changes to the preferences are committed to SharedPreferences automatically.

    0 讨论(0)
  • 2020-11-28 19:44

    All the other answers are correct. But I like this alternative better because you immediately have the Preference instance that caused the change.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Preference pref = findPreference(getString(R.string.key_of_pref));        
        pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                // do whatever you want with new value
    
                // true to update the state of the Preference with the new value
                // in case you want to disallow the change return false
                return true;
            }
        });
    }
    
    0 讨论(0)
提交回复
热议问题