web-dev-qa-db-fra.com

Comment actualisez-vous PreferenceActivity pour afficher les modifications apportées aux paramètres?

D'après le code suivant, pouvez-vous me dire comment actualiser la fenêtre PreferenceActivity pour afficher immédiatement les modifications apportées aux paramètres? Par exemple: l'utilisateur coche la case à cocher du carillon principal sur true (coché), j'aimerais que l'utilisateur voie immédiatement les autres paramètres tels que la case à cocher ChimeOn15Past soit également vrai (coché)

SharedPreferences.Editor prefEditor = clockSettings.edit(); // Allow the settings to be changed.

if (booleanMasterChimeToggle == true) {
    prefEditor.putBoolean("ChimeOnTheHour", true);
    prefEditor.putBoolean("ChimeOn15Past", true);
    prefEditor.putBoolean("ChimeOn30Past", true);
    prefEditor.putBoolean("ChimeOn45Past", true);

    strNotifyMessage = "Full chiming has now been set.";

} else {
    prefEditor.putBoolean("ChimeOnTheHour", false);
    prefEditor.putBoolean("ChimeOn15Past", false);
    prefEditor.putBoolean("ChimeOn30Past", false);
    prefEditor.putBoolean("ChimeOn45Past", false);

    strNotifyMessage = "Full chiming has now been disabled.";
}
27
Emad-ud-deen

La réponse de Nikolay est correcte. Je veux juste ajouter du code ici pour illustrer son propos plus clairement.

private CheckBoxPreference mOn15Past;
private CheckBoxPreference mOn30Past;
private CheckBoxPreference mOn45Past;

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

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

    mOn15Past = (CheckBoxPreference) findPreference("ChimeOn15Past");
    mOn30Past = (CheckBoxPreference) findPreference("ChimeOn30Past");
    mOn45Past = (CheckBoxPreference) findPreference("ChimeOn45Past");

    final Preference chimeMaster = findPreference("ChimeMaster");
    chimeMaster.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newVal) {
            final boolean value = (Boolean) newVal;
            mOn15Past.setChecked(value);
            mOn30Past.setChecked(value);
            mOn45Past.setChecked(value);
            return true;
        }

    });
}

En bref, PreferenceActivity n'est pas conçu pour actualiser ses valeurs à partir du stockage persistant une fois démarré. Au lieu d'utiliser SharedPreferences.Editor pour modifier et valider des modifications supplémentaires comme vous l'avez fait dans votre code, il est préférable de les modifier dans l'objet PreferenceManager local qui sera validé par la variable PreferenceActivity dans son cycle de vie normal.

28
Joe

Au lieu de

finish();
startActivity(getIntent());

Je préfère le code suivant:

setPreferenceScreen(null);
addPreferencesFromResource(R.xml.preferences);

Cela réinitialisera également l'affichage mais sans l'ensemble de la procédure finish et ses conséquences . De plus, ce code fonctionne bien avec PreferenceActivity et PreferenceFragment.

Ceci est intéressant si vous souhaitez modifier dynamiquement la valeur de la locale par exemple. Dans ce cas, travailler avec le responsable ne suffit pas car vous souhaitez un rechargement complet des titres et des valeurs.

EDIT: setPreferenceScreen est obsolète dans PreferenceActivity (fonctionne toujours) mais n'est pas dans PreferenceFragment

39
Solostaran14

Il existe une méthode simple pour actualiser tous les éléments de la liste simultanément. Faites simplement ce qui suit:

getPreferenceScreen().removeAll();
addPreferencesFromResource(R.xml.preferences);

Avec cette approche, vous ne perdrez pas la position de ListView.

13
Marcel Wesołowski

Implémentez onPreferenceChange et basculez les perfs associés à partir de là. Pour "actualiser" l'ensemble de l'activité, vous devez finish() et le redémarrer. 

3
Nikolay Elenkov

Après avoir combattu cela pendant un jour, j'ai compris cela.
Cela concerne plusieurs niveaux de préférences.

parent est l’écran des préférences qui contient la préférence que vous essayez de mettre à jour.

Puisque l’écran des paramètres s’affiche sous la forme d’une boîte de dialogue, vous pouvez obtenir la liste dans la boîte de dialogue, puis indiquer à son adaptateur de mettre à jour enfant.

PreferenceScreen parent  // The screen holding the child
PreferenceScreen child   // The entry changing

child.setSummary(isEnabled?"Enabled":"Not Enabled");
ListView v = (ListView)parent.getDialog().findViewById(Android.R.id.list);
BaseAdapter ba = (BaseAdapter)v.getAdapter();
ba.notifyDataSetChanged();

J'ai trouvé R.id.list n'est pas disponible sur les téléphones plus anciens, mais cela fonctionne

    ListAdapter adapter = parent.getRootAdapter();
    if (adapter instanceof BaseAdapter) {
        ((BaseAdapter)adapter).notifyDataSetChanged();
    }
1
Sailforms Developer

Vous pouvez simplement appeler la méthode onCreate. Si vous le souhaitez, vous pouvez appeler les méthodes onStart et onResume.

onCreate(null);

J'ai résolu mon problème de cette façon.

1
Arda Ç.

Cette classe indique l'écran de préférence simple. Ce qui peut vous aider.

public class PreferenceActivitySettings extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
        private SharedPreferences preferences;
        @SuppressWarnings("deprecation")
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.settings);
            preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
            preferences.registerOnSharedPreferenceChangeListener(this);
        }

        @SuppressWarnings("deprecation")
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            setPreferenceScreen(null);
            addPreferencesFromResource(R.xml.settings);
        }
    }
0
Vinil Chandran

J'ai réussi à écrire une méthode qui est en fait assez simple et sans avoir besoin d'invalider ListViews ou peu importe la situation. Cette méthode appelle les public ViewGroup removeView(View view), View requestLayout(), View forceLayout(), ViewGroup addView(View view) et enfin un appel aux méthodes Fragment OnCreate(Bundle savedInstanceState) avec quelques contrôles nuls et une variable temporaire final View pour stocker la vue réelle lorsque celle-ci est supprimée.

Cette méthode est encore nouvelle et je vais la peaufiner et la peaufiner au cours des deux prochains jours, mais elle fonctionne parfaitement telle quelle, sans aucun effet secondaire. Étant donné que la classe que j'ai écrite en tenant le code modifie le style de préférence actuel et les styles de texte de synthèse pour la totalité de la rom (ce qui était tout à fait le cas des options que j'ai ajoutées), j'ai également ajouté un constructeur public aux classes en question. les activités qui se trouvent dans la pile d’activités en dessous de l’écran de style de préférence pour pouvoir être mises à jour simultanément. Il est fort probable que je déplacerai cette nouvelle méthode dans la classe de vue frameworks afin de la mettre à la disposition du système.

public void reLoadView(View view) {
    if (view == null) {
        view = mView;
        Log.i(TAG, "The current View is: " + view);
    }
    final View tmpView = view;
    try {
        setStyleChanged(1);
        setReset(0);
        Log.i(TAG, "The Temporary View is: " + tmpView);
        Log.i(TAG, "The current View is: " + mView);
        Log.i(TAG, "The current ViewGroup is: " + mViewGroup);
        if (mView != null) {
            if (mViewGroup != null) {
                mActivity.runOnUiThread(new Runnable() {
                    @Override 
                    public void run() {
                        mViewGroup.removeView(mView);
                        mView.requestLayout();
                        mView.forceLayout();
                        mViewGroup.addView(tmpView);
                        onCreate(new Bundle());
                    } 
                });
            }
        }
        View tmp = null;
        mDemented.reLoadView(tmp);
    } catch (Exception e) {
    }
}

Les variables de vue elles-mêmes sont définies initialement dans l'initialisation de la classe et sont initialisées et définies dans les fonctions View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) et View onViewCreated(View view, Bundle savedInstanceState). Les variables de vue elles-mêmes sont définies initialement dans l'initialisation de la classe.

private View mView;
private ViewGroup mViewGroup;

private int mLayoutResId = R.layout.preference_list_fragment;//holds the layout reference just to keep it clean
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    View rootView = inflater.inflate(mLayoutResId, parent, false);
    mViewGroup = parent;
    return rootView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    mView = view;
}

Dans les activités de la pile ci-dessous, ma classe PreferenceStyle, j'ai défini un constructeur vide pouvant être initialisé n'importe où dans l'application. 

public class DEMENTED extends SettingsPreferenceFragment implements
        Preference.OnPreferenceChangeListener, View.OnClickListener {

    public DEMENTED() {
         super();
    }

    //other code to do whatever here

Dans ma classe PreferenceStyle, j'ai importé ma classe DEMENTED, puis je l'ai définie comme variable avant onCreate(Bundle savedInstanceState):

private DEMENTED mDemented;

Puis initialisé la variable dans onCreate(Bundle savedInstanceState):

mDemented = new DEMENTED();

L'appel à ma classe DEMENTED pour recharger sa vue est effectué dans ma méthode reloadView(View view), mais la vue de variable utilisée pour effectuer l'appel est une variable View immédiatement antérieure à l'appel et définie sur null:

View tmp = null;
mDemented.reLoadView(tmp);

et ma classe DEMENTED vérifie si la vue incluse dans l'appel de méthode est nulle et, si tel est le cas, elle est définie sur une variable View localisée afin que la méthode puisse fonctionner avec les variables locales:

public void reLoadView(View view) {
    if (view == null) {
        view = mView;
        Log.i(TAG, "The current View is: " + view);
    }
    //all the other good stuff here

Fondamentalement, ceci utilise le ViewGroup tel que défini dans onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState):

    mViewGroup = parent;

et la variable View est définie dans onViewCreated(View view, Bundle savedInstanceState)

    mView = view;

J'espère que cela va aider quelqu'un parce que c'est une question que j'ai répétée maintes et maintes fois et que je n'ai pas encore trouvé de solution solide, essentiellement n'importe où n'impliquant pas plusieurs classes utilisées en tant qu'utils. Si quelqu'un a des suggestions de commentaires à simplifier ou quoi que ce soit, n'hésitez pas à les commenter.

0
cphelps76

Une fois que vous avez validé les modifications apportées aux sharedPreferences, vous devriez simplement appeler invalidateHeaders () . Docs à ce sujet:

Appelez lorsque vous devez modifier les en-têtes affichés. Résultera dans onBuildHeaders () étant appelé ultérieurement pour récupérer la nouvelle liste.

Cela devrait actualiser l'interface utilisateur, pour afficher les nouvelles valeurs.

0
android developer