83 votes

Comment faire passer des données entre fragments

J'essaie de faire passer des données entre deux fragments dans mon programme. C'est juste une simple chaîne de caractères qui est stockée dans la liste. La liste est rendue publique dans le fragment A, et lorsque l'utilisateur clique sur un élément de la liste, j'ai besoin qu'il apparaisse dans le fragment B. Le fournisseur de contenu ne semble supporter que les ID, donc cela ne fonctionnera pas. Avez-vous des suggestions ?

0 votes

0 votes

58voto

Fedor Points 29890

Je pense que la communication entre les fragments devrait se faire par le biais d'une activité. Et la communication entre le fragment et l'activité peut être faite de cette façon http://developer.Android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity .

21voto

Donn Felker Points 3501

Si vous utilisez Roboguice, vous pouvez utiliser l'EventManager de Roboguice pour faire circuler les données sans utiliser l'Activity comme interface. C'est assez propre, selon moi.

Si vous n'utilisez pas Roboguice, vous pouvez également utiliser Otto comme bus d'événements : http://square.github.com/otto/

Mise à jour 20150909 : Vous pouvez également utiliser le bus événementiel de Green Robot ou même RxJava maintenant. Cela dépend de votre cas d'utilisation.

3 votes

Je suis de tout cœur avec ce que dit Donn ici. Utilisez un bus et démêlez tout ça et arrêtez d'écrire des listeners et des callbacks manuellement. Otto FTW.

0 votes

Si vous ne voulez pas utiliser RoboGuice, vous pouvez utiliser Otto de Square. J'utilise Otto assez souvent maintenant et c'est EXCELLENT. github.com/square/otto

9 votes

Si vous aimez Otto, vous apprécierez peut-être aussi EventBus, qui offre en plus la gestion des fils. github.com/greenrobot/EventBus

17voto

Jens Kohl Points 2407

De la Fragment documentation :

Souvent, vous voudrez qu'un fragment communique avec un autre, par exemple pour modifier le contenu en fonction d'un événement utilisateur. Toute communication entre fragments se fait par le biais de l'activité associée. Deux fragments ne doivent jamais communiquer directement.

Je vous suggère donc de consulter le site docs de formation de base sur les fragments dans la documentation. Elle est assez complète, avec un exemple et un guide d'utilisation.

12voto

Gene Points 398

Disons que vous avez l'activité AB qui contrôle le fragment A et le fragment B. À l'intérieur du fragment A, vous avez besoin d'une interface que l'activité AB peut mettre en œuvre. Dans l'exemple de code Android, ils ont :

private Callbacks mCallbacks = sDummyCallbacks;

/*Une interface de rappel que toutes les activités contenant ce fragment doivent mettre en œuvre. Ce mécanisme permet aux activités d'être notifiées des sélections d'éléments. */

public interface Callbacks {
/*Callback for when an item has been selected. */    
      public void onItemSelected(String id);
}

/*A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */    
private static Callbacks sDummyCallbacks = new Callbacks() {
    @Override
    public void onItemSelected(String id) {
    }
};

L'interface Callback est placée dans l'un de vos fragments (disons le fragment A). Je pense que le but de cette interface CallBacks est comme une classe imbriquée à l'intérieur du Fragment A que n'importe quelle activité peut implémenter. Ainsi, si le fragment A est un téléviseur, l'interface CallBacks est la télécommande du téléviseur (interface) qui permet au fragment A d'être utilisé par l'activité AB. Je peux me tromper sur les détails parce que je suis un noob mais j'ai réussi à faire fonctionner mon programme parfaitement sur toutes les tailles d'écran et c'est ce que j'ai utilisé.

Donc à l'intérieur du Fragment A, nous avons : (J'ai pris ça dans les programmes d'exemple d'Android)

@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
//mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, String, etc.);
//mCallbacks.onItemSelected (Object);
}

Et dans l'activité AB, nous surchargeons la méthode onItemSelected :

public class AB extends FragmentActivity implements ItemListFragment.Callbacks {
//...
@Override
//public void onItemSelected (CATCH YOUR SHIT HERE) {
//public void onItemSelected (Object obj) {
    public void onItemSelected(String id) {
    //Pass Data to Fragment B. For example:
    Bundle arguments = new Bundle();
    arguments.putString(“FragmentB_package”, id);
    FragmentB fragment = new FragmentB();
    fragment.setArguments(arguments);
    getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit();
    }

Ainsi, à l'intérieur de l'activité AB, vous placez tout dans un Bundle et le transmettez à B. Si vous n'êtes pas sûr de savoir comment utiliser un Bundle, consultez la classe.

Je me base sur l'exemple de code fourni par Android. Celui avec le truc DummyContent. Lorsque vous créez un nouveau package d'application Android, c'est celui intitulé MasterDetailFlow.

2voto

Pier Betos Points 41

Cela dépend de la façon dont le fragment est structuré. Si vous pouvez avoir certaines des méthodes sur la classe de fragment B statique et aussi l'objet TextView cible statique, vous pouvez appeler la méthode directement sur la classe de fragment A. C'est mieux qu'un écouteur car la méthode est exécutée instantanément, et nous n'avons pas besoin d'avoir une tâche supplémentaire qui effectue l'écoute tout au long de l'activité. Voir l'exemple ci-dessous :

Fragment_class_B.setmyText(String yourstring);

Sur le fragment B, la méthode peut être définie comme suit :

public static void setmyText(final String string) {
myTextView.setText(string);
}

N'oubliez pas de définir myTextView comme static sur le Fragment B et d'importer correctement la classe du Fragment B sur le Fragment A.

J'ai fait cette procédure sur mon projet récemment et ça a marché. J'espère que cela vous a aidé.

2 votes

Cela fonctionnera (enfin, jusqu'à ce que le fragment soit détruit et recréé, pensez à la rotation du dispositif) mais vous couplez étroitement les fragments ; le fragment dépendant (appelons-le 'X') a une dépendance câblée dans son code sur l'autre fragment ('Y'). Passer par l'activité parente est beaucoup plus propre car vous pouvez laisser à l'activité le soin de décider d'où obtenir les données. Par exemple, sur un téléphone, votre activité peut utiliser les fragments X et Y, mais sur une tablette, vous pouvez décider d'utiliser X et Z. Il est préférable de laisser l'activité (qui sait quels fragments existent) agir comme intermédiaire et se connecter à Y ou Z selon le cas.

0 votes

Et si on appelait l'Asyntask depuis cette méthode ?

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