97 votes

Comment écouter les changements de préférences dans un PreferenceFragment ?

Comme décrit aquí Je suis en train de sous-classer PreferenceFragment et de l'afficher dans une activité. Ce document explique comment écouter les changements de préférences aquí mais seulement si vous sous-classez PreferenceActivity. Puisque je ne fais pas cela, comment puis-je écouter les changements de préférences ?

J'ai essayé d'implémenter le OnSharedPreferenceChangeListener dans mon PreferenceFragment mais cela ne semble pas fonctionner ( onSharedPreferenceChanged ne semble jamais être appelé).

Voici mon code jusqu'à présent :

SettingsActivity.java

public class SettingsActivity 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 SettingsFragment()).commit();
    }
}

SettingsFragment.java

public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener
{
    public static final String KEY_PREF_EXERCISES = "pref_number_of_exercises";

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

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
    {
        //IT NEVER GETS IN HERE!
        if (key.equals(KEY_PREF_EXERCISES))
        {
            // Set summary to be the user-description for the selected value
            Preference exercisesPref = findPreference(key);
            exercisesPref.setSummary(sharedPreferences.getString(key, ""));
        }
    }
}

préférences.xml

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

    <EditTextPreference
        android:defaultValue="15"
        android:enabled="true"
        android:key="pref_number_of_exercises"
        android:numeric="integer"
        android:title="Number of exercises" />

</PreferenceScreen>

De plus, le PreferenceFragment est-il le bon endroit pour écouter les changements de préférences ou dois-je le faire dans l'activité ?

157voto

antew Points 4118

Je crois qu'il suffit d'enregistrer ou de désenregistrer l'interface de l'utilisateur. Listener dans votre PreferenceFragment et ça marchera.

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

}

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

En fonction de ce que vous voulez faire, vous n'aurez peut-être pas besoin d'utiliser un écouteur. Les modifications apportées aux préférences sont enregistrées dans le fichier SharedPreferences automatiquement.

25voto

Gunnar Bernstein Points 853

La solution d'antew fonctionne bien, ici vous pouvez voir une activité de préférence complète pour Android v11 et plus :

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");

    }
}
}

17voto

Zsolt Safrany Points 1688

Toutes les autres réponses sont correctes. Mais je préfère cette alternative car vous avez immédiatement l'instance de la préférence qui a causé le changement.

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

2voto

gnB Points 760

Ceci a fonctionné pour moi à partir de PreferenceFragment.onCreate()

OnSharedPreferenceChangeListener listener = 
    new SharedPreferences.OnSharedPreferenceChangeListener()
    {
        public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
        {
         showDialog();
        }
    };

1voto

Eaweb Points 119

Voici une façon de le faire et d'éviter toute fuite de mémoire potentielle :

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    addPreferencesFromResource(R.xml.pref_movies);

    SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences(); 

    //starts live change listener
    sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onDestroyView () {
    super.onDestroyView(); 
//Unregisters listener here
    PreferenceManager.getDefaultSharedPreferences(getContext())
            .unregisterOnSharedPreferenceChangeListener(this);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X