365 votes

Ce qu’il faut utiliser au lieu de « addPreferencesFromResource » dans un PreferenceActivity ?

Je viens de remarquer le fait que la méthode de addPreferencesFromResource(int preferencesResId) est marquée obsolète dans Android documentation (Entrée de Référence).

Malheureusement, aucune méthode alternative n'est prévue dans la méthode de description.

La méthode qui devrait être utilisée à la place afin de connecter un preferenceScreen.xml pour la mise en correspondance PreferenceActivity?

Merci beaucoup pour votre aide.

334voto

glorifiedHacker Points 4725

Aucune méthode alternative n’est fournie dans la description de la méthode, car l’approche privilégiée (au niveau de l’API 11) consiste à instancier les objets PreferenceFragment pour charger vos préférences à partir d’un fichier de ressources. Voir l’exemple de code ici : PreferenceActivity

188voto

Garret Wilson Points 2583

Pour ajouter plus d'informations à la bonne réponse ci-dessus, après la lecture d'un exemple de Android-er j'ai trouvé, vous pouvez facilement convertir votre activité de préférence dans un fragment de préférence. Si vous avez de l'activité suivante:

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.my_preference_screen);
    }
}

Les seules modifications que vous avez à faire est de créer un fragment interne de la classe, de déplacer l' addPreferencesFromResources() dans le fragment, et d'invoquer le fragment de l'activité, comme ceci:

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
    }

    public static class MyPreferenceFragment extends PreferenceFragment
    {
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.my_preference_screen);
        }
    }
}

Il y a peut être d'autres subtilités à rendre plus complexes les préférences à partir de fragments; si oui, j'espère que quelqu'un notes ici.

38voto

Kevin Remo Points 507

@Garret Wilson Merci beaucoup! Comme un noob pour android codage, j'ai été coincé avec les préférences de problème d'incompatibilité pendant de nombreuses heures, et je trouve ça tellement décevant qu'ils obsolète l'utilisation de certaines méthodes/approches pour les nouveaux qui ne sont pas pris en charge par l'ancienne Api ainsi d'avoir à recourir à toutes sortes de solutions pour faire de votre application de fonctionner dans une large gamme d'appareils. C'est vraiment frustrant!

Votre classe est grande, car il permet de continuer à travailler dans la nouvelle Api à l'aide des préférences de la façon dont il l'habitude d'être, mais il n'est pas rétro-compatible. Depuis que je suis en train d'essayer de parvenir à un large éventail de périphériques, j'ai bricolé un peu pour le faire fonctionner en pré API 11 appareils ainsi que dans les nouvelles Api:

import android.annotation.TargetApi;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;

public class MyPrefsActivity extends PreferenceActivity
{
    private static int prefs=R.xml.myprefs;

    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        try {
            getClass().getMethod("getFragmentManager");
            AddResourceApi11AndGreater();
        } catch (NoSuchMethodException e) { //Api < 11
            AddResourceApiLessThan11();
        }
    }

    @SuppressWarnings("deprecation")
    protected void AddResourceApiLessThan11()
    {
        addPreferencesFromResource(prefs);
    }

    @TargetApi(11)
    protected void AddResourceApi11AndGreater()
    {
        getFragmentManager().beginTransaction().replace(android.R.id.content,
                new PF()).commit();
    }

    @TargetApi(11)
    public static class PF extends PreferenceFragment
    {       
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(MyPrefsActivity.prefs); //outer class
            // private members seem to be visible for inner class, and
            // making it static made things so much easier
        }
    }
}

Testé dans deux émulateurs (2.2 et 4.2) avec succès.

Pourquoi mon code ressemble tellement merdique:

Je suis un noob de android de codage, et je ne suis pas le plus grand java ventilateur.

Afin d'éviter le obsolète avertissement et à la force de l'Éclipse pour me permettre de compiler, j'ai dû recourir à des annotations, mais il semble affecter que des classes ou des méthodes, de sorte que j'ai dû passer le code sur deux nouvelles méthodes pour profiter de cette.

Je ne voudrais pas avoir à écrire mon xml id de ressource à deux fois quand je copie et colle la classe pour une nouvelle PreferenceActivity, j'ai donc créé une nouvelle variable pour stocker cette valeur.

J'espère que ce sera utile à quelqu'un d'autre.

P. S.: Désolé pour mes opinions points de vue, mais quand vous venez de nouvelles et de trouver ces handicaps, vous ne pouvez pas aider, mais pour aller à la frustration!

22voto

schnatterer Points 730

Mon approche est très proche de Garret Wilson (merci, j'ai voté en vous ;)

En outre, il fournit à la baisse de la compatibilité avec Android < 3.

J'ai juste reconnu que ma solution est encore plus proche de l'un par Kevin Remo. C'est juste un tout petit peu plus propre (car il ne repose pas sur la "exception" antipattern).

public class MyPreferenceActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            onCreatePreferenceActivity();
        } else {
            onCreatePreferenceFragment();
        }
    }

    /**
     * Wraps legacy {@link #onCreate(Bundle)} code for Android < 3 (i.e. API lvl
     * < 11).
     */
    @SuppressWarnings("deprecation")
    private void onCreatePreferenceActivity() {
        addPreferencesFromResource(R.xml.preferences);
    }

    /**
     * Wraps {@link #onCreate(Bundle)} code for Android >= 3 (i.e. API lvl >=
     * 11).
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void onCreatePreferenceFragment() {
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new MyPreferenceFragment ())
                .commit();
    }
}

Pour un "vrai" (mais plus complexe) exemple voir NusicPreferencesActivity et NusicPreferencesFragment.

6voto

Peter Points 59

Au lieu d’exceptions près, il suffit d’utiliser :

et l’utilisation

pour supprimer les avertissements.

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