Comment passer une variable d'Activité à Fragment et la renvoyer?

135

Je crée actuellement une application Android et je souhaite passer une date entre l'activité et le fragment. Mon activité a un bouton, qui ouvre le fragment: DatePickerFragment.

Dans mon activité, je montre une date, que je souhaite modifier avec le fragment. Je souhaite donc transmettre la date au sélecteur de date et la renvoyer à l'activité.

J'ai essayé beaucoup de solutions, mais aucune ne fonctionne. Le moyen le plus simple de passer un argument, mais cela ne peut pas être fait avec des fragments.

Eugène Primako
la source
Mon problème est exactement le même que le vôtre. Je me demande pourquoi les exemples ne traitent que les fragments eux-mêmes comme les "utilisateurs" du sélecteur de dates, et non comme l'activité qui les a déclenchés.
Claudio

Réponses:

213

Pour transmettre des informations à un fragment , vous définissezArguments lors de sa création et vous pourrez récupérer cet argument ultérieurement sur la méthode onCreate ou onCreateView de votre fragment.

Sur la fonction newInstance de votre fragment, vous ajoutez les arguments que vous souhaitez lui envoyer:

/**
 * Create a new instance of DetailsFragment, initialized to
 * show the text at 'index'.
 */
public static DetailsFragment newInstance(int index) {
    DetailsFragment f = new DetailsFragment();
    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putInt("index", index);
    f.setArguments(args);
    return f;
}

Puis à l'intérieur du fragment sur la méthode onCreateou onCreateViewvous pouvez récupérer les arguments comme ceci:

Bundle args = getArguments();
int index = args.getInt("index", 0);

Si vous souhaitez maintenant communiquer à partir de votre fragment avec votre activité (envoi ou non de données) , vous devez utiliser des interfaces. La manière dont vous pouvez le faire est très bien expliquée dans le tutoriel de documentation sur la communication entre fragments. Étant donné que tous les fragments communiquent entre eux via l'activité, dans ce didacticiel, vous pouvez voir comment envoyer des données du fragment réel à son conteneur d'activités pour utiliser ces données sur l'activité ou les envoyer à un autre fragment que contient votre activité.

Tutoriel de documentation:

http://developer.android.com/training/basics/fragments/communicating.html

jpardogo
la source
10
Je pense que l'intérêt des gens qui posent cette question encore et encore est que ce n'est pas vraiment bien expliqué dans la documentation.
Michael Alan Huff
1
Je ne sais toujours pas quelle méthode est la meilleure à utiliser, la vôtre ou celle ci-dessous répondu par @Elenasys
Yoann Hercouet
Il existe une nouvelle façon de partager des données entre fragments à l'aide de composants d'architecture (I / O '17): developer.android.com/topic/libraries/architecture
...
Qu'en est-il de ces fragments créés dans la mise en page XML?
ralphgabb
Je ne veux plus utiliser de méthode statique.
Ahamadullah Saikat le
89

Envoi de données Activityà unFragment

Activité:

Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();

Fragment:

Lecture de la valeur en fragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    String myValue = this.getArguments().getString("message");
    ...
    ...
    ...
}

Mais si vous voulez envoyer des valeurs de Fragment à Activity, lisez la réponse de jpardogo, vous devez avoir besoin d'interfaces, plus d'informations: Communiquer avec d'autres fragments

Jorgesys
la source
2
Comment passer un objet personnalisé? J'ai utilisé Parcelablemais cela m'a donnéclass cast exception
viper
cette solution ne fonctionne pas pour moi, je ne trouve pas d'où importer la transaction
thebeancounter
Eh bien, si vous chargez le fragment dans votre activité, vous pouvez envoyer des valeurs via le bundle défini dans votre transaction. Expliquez quel est votre scénario?
Jorgesys
8

merci à @ ρяσѕρєя K et Terry ... cela m'aide beaucoup et fonctionne parfaitement

À partir de l'activité, vous envoyez des données avec l'intention comme:

Bundle bundle = new Bundle(); 
bundle.putString("edttext", "From Activity"); 
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

et dans la méthode Fragment onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // get arguments
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

référence: envoyer des données d'activité à fragmenter dans Android

mahmoud zaher
la source
7

Utilisez la bibliothèque EventBus pour transmettre des événements qui pourraient contenir votre variable d'avant en arrière. C'est une bonne solution car elle maintient vos activités et fragments faiblement couplés

https://github.com/greenrobot/EventBus

SémaphoreMétaphore
la source
4
Je ne peux pas dire que ce n'est pas une bonne solution, mais une mise en garde est en place. Bien qu'EventBus soit extrêmement facile à utiliser, c'est là aussi son danger. Si vous commencez à ajouter trop de signaux, la nature faiblement couplée peut rendre très difficile de savoir qui appelle qui et où les différents événements ont lieu.
Johan Paul
2

Pour tous les développeurs Kotlin là-bas:

Voici la solution proposée par Android Studio pour envoyer des données à votre Fragment (= lorsque vous créez un Blank-Fragment avec File -> New -> Fragment -> Fragment (Blank) et que vous cochez "include fragment factory methods").

Mettez ceci dans votre Fragment:

class MyFragment: Fragment {

...

    companion object {

            @JvmStatic
            fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
                arguments = Bundle().apply {
                    putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
                }
            }
     }
}

.applyest une belle astuce pour définir des données lors de la création d'un objet, ou comme ils l'indiquent ici :

Appelle la fonction spécifiée [bloc] avec thisvaleur comme récepteur et renvoie thisvaleur.

Ensuite, dans votre activité ou fragment, faites:

val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here

et lisez les arguments dans votre fragment tels que:

private var isMyBoolean = false

override fun onAttach(context: Context?) {
    super.onAttach(context)
    arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
        isMyBoolean = it
    }
}

Pour «renvoyer» des données à votre activité , définissez simplement une fonction dans votre activité et procédez comme suit dans votre fragment:

(activity as? YourActivityClass)?.callYourFunctionLikeThis(date) // your function will not be called if your Activity is null or is a different Class

Profitez de la magie de Kotlin!

Paul Spiesberger
la source
1

Envoi de données depuis l'activité vers des fragments liés par XML

Si vous créez un fragment dans Android Studio à l'aide de l'un des modèles, par exemple Fichier> Nouveau> Fragment> Fragment (Liste), le fragment est lié via XML. La méthode newInstance est créée dans le fragment mais n'est jamais appelée et ne peut donc pas être utilisée pour passer des arguments.

Au lieu de cela, dans l'activité, remplacez la méthode onAttachFragment

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof DetailsFragment) {
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);        
     }
}

Ensuite, lisez les arguments de la méthode fragment onCreate selon les autres réponses

Vallée
la source
0

Vous pouvez simplement instancier votre fragment avec un bundle:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);
stef
la source