Recevoir le résultat de DialogFragment

J’utilise DialogFragments pour un certain nombre de choses: choisir un élément de la liste, entrer du texte.

Quelle est la meilleure façon de renvoyer une valeur (une chaîne ou un élément d’une liste) à l’activité / au fragment appelant?

Actuellement, je mets en activité l’activité d’appel DismissListener et donne au DialogFragment une référence à l’activité. Le dialog appelle alors la méthode OnDimiss dans l’activité et l’activité récupère le résultat de l’object DialogFragment. Très désordonné et il ne fonctionne pas sur les modifications de configuration (changement d’orientation) car le DialogFragment perd la référence à l’activité.

Merci pour toute aide.

Utilisez myDialogFragment.setTargetFragment(this, MY_REQUEST_CODE) à l’endroit où vous affichez la boîte de dialog, puis lorsque votre boîte de dialog est terminée, vous pouvez appeler getTargetFragment().onActivityResult(getTargetRequestCode(), ...) et implémenter onActivityResult() dans le fragment contenant.

Cela semble être un abus de onActivityResult() , d’autant plus que cela n’implique aucune activité. Mais je l’ai vu recommandé par les gens de Google officiels, et peut-être même dans les démos api. Je pense que c’est ce que g/setTargetFragment() été ajouté pour.

Comme vous pouvez le voir ici, il existe un moyen très simple de le faire.

Dans votre DialogFragment ajoutez un écouteur d’interface tel que:

 public interface EditNameDialogListener { void onFinishEditDialog(Ssortingng inputText); } 

Ensuite, ajoutez une référence à cet écouteur:

 private EditNameDialogListener listener; 

Ceci sera utilisé pour “activer” la ou les méthodes d’écoute, et aussi pour vérifier si l’activité / le fragment parent implémente cette interface (voir ci-dessous).

Dans Activity / FragmentActivity / Fragment qui a “appelé” le DialogFragment implémentez simplement cette interface.

Dans votre DialogFragment tout ce que vous devez append au moment où vous souhaitez DialogFragment le DialogFragment et renvoyer le résultat est le suivant:

 listener.onFinishEditDialog(mEditText.getText().toSsortingng()); this.dismiss(); 

mEditText.getText().toSsortingng() est ce qui sera renvoyé à l’ Activity appelante.

Notez que si vous voulez retourner quelque chose, changez simplement les arguments de l’auditeur.

Enfin, vous devriez vérifier si l’interface a été réellement implémentée par l’activité / fragment parent:

 @Override public void onAttach(Context context) { super.onAttach(context); // Verify that the host activity implements the callback interface try { // Instantiate the EditNameDialogListener so we can send events to the host listener = (EditNameDialogListener) context; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(context.toSsortingng() + " must implement EditNameDialogListener"); } } 

Cette technique est très flexible et permet de rappeler le résultat même si vous ne voulez pas encore supprimer la boîte de dialog.

Il existe un moyen beaucoup plus simple de recevoir un résultat d’un DialogFragment.

Tout d’abord, dans votre activité, fragment ou fragmentation, vous devez append les informations suivantes:

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { // Stuff to do, dependent on requestCode and resultCode if(requestCode == 1) { // 1 is an arbitrary number, can be any int // This is the return result of your DialogFragment if(resultCode == 1) { // 1 is an arbitrary number, can be any int // Now do what you need to do after the dialog dismisses. } } } 

Le requestCode est fondamentalement votre label int pour le DialogFragment que vous avez appelé, je montrerai comment cela fonctionne en une seconde. Le resultCode est le code que vous renvoyez depuis le DialogFragment, indiquant votre activité en cours, son fragment ou son fragmentActivity.

Le prochain morceau de code à entrer est l’appel au DialogFragment. Un exemple est ici:

 DialogFragment dialogFrag = new MyDialogFragment(); // This is the requestCode that you are sending. dialogFrag.setTargetFragment(this, 1); // This is the tag, "dialog" being sent. dialogFrag.show(getFragmentManager(), "dialog"); 

Avec ces trois lignes, vous déclarez votre DialogFragment, en définissant un requestCode (qui appellera le onActivityResult (…) une fois le dialog supprimé et vous afficherez alors la boîte de dialog. C’est aussi simple que cela.

Maintenant, dans votre DialogFragment, vous devez simplement append une ligne directement avant le dismiss() pour que vous renvoyiez un resultCode au onActivityResult ().

 getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, getActivity().getIntent()); dismiss(); 

C’est tout. Notez que le resultCode est défini comme int resultCode que j’ai défini sur resultCode = 1; dans ce cas.

Ça y est, vous pouvez maintenant renvoyer le résultat de votre DialogFragment à votre activité, fragment ou fragmentation.

En outre, il semble que cette information ait été publiée précédemment, mais il n’ya pas eu d’exemple suffisant, alors j’ai pensé fournir plus de détails.

EDIT 24.06.2016 Je m’excuse pour le code trompeur ci-dessus. Mais vous ne pouvez certainement pas recevoir le résultat de l’activité en considérant la ligne:

 dialogFrag.setTargetFragment(this, 1); 

définit un Fragment cible et non une Activity . Donc, pour ce faire, vous devez utiliser implémenter InterfaceCommunicator .

Dans votre DialogFragment définissez une variable globale

 public InterfaceCommunicator interfaceCommunicator; 

Créer une fonction publique pour le gérer

 public interface InterfaceCommunicator { void sendRequestCode(int code); } 

Ensuite, lorsque vous êtes prêt à renvoyer le code à l’ Activity lorsque le DialogFragment est terminé, vous ajoutez simplement la ligne avant de dismiss(); votre DialogFragment :

 interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose. 

Dans votre activité, vous devez maintenant faire deux choses: la première consiste à supprimer cette ligne de code qui ne s’applique plus:

 dialogFrag.setTargetFragment(this, 1); 

Ensuite, implémentez l’interface et vous avez terminé. Vous pouvez le faire en ajoutant la ligne suivante à la clause implements tout en haut de votre classe:

 public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator 

Et puis @Override la fonction dans l’activité,

 @Override public void sendRequestCode(int code) { // your code here } 

Vous utilisez cette méthode d’interface comme vous le feriez avec la méthode onActivityResult() . Sauf que la méthode d’interface est pour DialogFragments et l’autre pour Fragments .

Eh bien, il est peut-être trop tard pour répondre, mais voici ce que j’ai fait pour obtenir des résultats du DialogFragment . très similaire à la réponse de @ brandon. Ici, DialogFragment partir d’un fragment, placez simplement ce code à l’endroit où vous appelez votre boîte de dialog.

 FragmentManager fragmentManager = getFragmentManager(); categoryDialog.setTargetFragment(this,1); categoryDialog.show(fragmentManager, "dialog"); 

categoryDialog est mon DialogFragment que je veux appeler et après cela, dans votre implémentation de dialogfragment placez ce code à l’endroit où vous définissez vos données. La valeur de resultCode est 1, vous pouvez la définir ou utiliser le système défini.

  Intent intent = new Intent(); intent.putExtra("listdata", ssortingngData); getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent); getDialog().dismiss(); 

il est maintenant temps de revenir au fragment d’appel et d’implémenter cette méthode. vérifiez la validité des données ou le résultat si vous souhaitez que resultCode et resultCode dans la condition if.

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //do what ever you want here, and get the result from intent like below Ssortingng myData = data.getSsortingngExtra("listdata"); Toast.makeText(getActivity(),data.getSsortingngExtra("listdata"),Toast.LENGTH_SHORT).show(); } 

Je suis très surpris de voir que personne n’a suggéré d’utiliser les diffusions locales pour la communication DialogFragment to Activity ! Je trouve que c’est beaucoup plus simple et plus propre que d’autres suggestions. Essentiellement, vous vous inscrivez à votre Activity pour écouter les émissions et vous envoyez les émissions locales à partir de vos instances DialogFragment . Simple. Pour un guide étape par étape sur la façon de tout configurer, voir ici .

Un moyen simple que j’ai trouvé était le suivant: Implémenter ceci est votre dialog de dialog,

  CallingActivity callingActivity = (CallingActivity) getActivity(); callingActivity.onUserSelectValue("insert selected value here"); dismiss(); 

Et puis, dans l’activité qui a appelé le fragment de dialog, créez la fonction appropriée en tant que telle:

  public void onUserSelectValue(Ssortingng selectedValue) { // TODO add your implementation. Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show(); } 

Le Toast est de montrer que cela fonctionne. Travaillé pour moi

Une approche différente, pour permettre à un fragment de communiquer jusqu’à son activité :

1) Définir une interface publique dans le fragment et créer une variable pour celui-ci

 public OnFragmentInteractionListener mCallback; public interface OnFragmentInteractionListener { void onFragmentInteraction(int id); } 

2) Convertissez l’activité dans la variable mCallback du fragment

 try { mCallback = (OnFragmentInteractionListener) getActivity(); } catch (Exception e) { Log.d(TAG, e.getMessage()); } 

3) Implémenter l’auditeur dans votre activité

 public class MainActivity extends AppCompatActivity implements DFragment.OnFragmentInteractionListener { //your code here } 

4) Remplacer le OnFragmentInteraction dans l’activité

 @Override public void onFragmentInteraction(int id) { Log.d(TAG, "received from fragment: " + id); } 

Plus d’informations à ce sujet: https://developer.android.com/training/basics/fragments/communicating.html

Dans mon cas, je devais passer des arguments à un fragment cible. Mais j’ai eu exception “Fragment déjà actif”. J’ai donc déclaré une interface dans mon DialogFragment qui parentfragment implémenté. Lorsque parentFragment a lancé un DialogFragment, il s’est défini comme TargetFragment. Ensuite, dans DialogFragment, j’ai appelé

  ((Interface)getTargetFragment()).onSomething(selectedListPosition); 

Juste pour l’avoir comme l’une des options (puisque personne ne l’a encore mentionné) – vous pourriez utiliser un bus d’événement comme Otto. Donc, dans la boîte de dialog que vous faites:

 bus.post(new AnswerAvailableEvent(42)); 

Et demandez à votre correspondant (Activité ou Fragment) de vous y abonner:

 @Subscribe public void answerAvailable(AnswerAvailableEvent event) { // TODO: React to the event somehow! }