Recevoir le résultat de DialogFragment

j'utilise DialogFragments pour un certain nombre de choses: choisir un élément de la liste, entrer le texte.

Quelle est la meilleure façon de retourner une valeur (c.-à-d. une chaîne ou un élément d'une liste) à l'activité d'appel/fragment?

actuellement je fais l'implémentation de l'activité appelant DismissListener et je donne au DialogFragment une référence à l'activité. Le dialogue appelle alors la méthode OnDimiss dans l'activité et l'activité saisit le résultat de L'objet DialogFragment. Très embrouillé et ne fonctionne pas sur le changement de configuration (changement d'orientation) car le fragment de dialogue perd la référence à l'activité.

Merci pour votre aide.

203
demandé sur ישו אוהב אותך 2012-06-06 01:35:08

9 réponses

utilisez myDialogFragment.setTargetFragment(this, MY_REQUEST_CODE) à partir de l'endroit où vous affichez la boîte de dialogue, puis lorsque votre boîte de dialogue est terminée, vous pouvez appeler getTargetFragment().onActivityResult(getTargetRequestCode(), ...) , et mettre en œuvre onActivityResult() dans le fragment contenant.

cela ressemble à un abus de onActivityResult() , d'autant plus qu'il n'implique aucune activité. Mais je l'ai vu recommandé par les gens officiels de google, et peut-être même dans les démonstrations de l'api. Je pense que c'est pour ça que g/setTargetFragment() a été ajouté.

222
répondu Timmmm 2013-02-14 14:47:58

comme vous pouvez le voir ici il y a une façon très simple de le faire.

dans votre DialogFragment ajouter un écouteur d'interface comme:

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

ensuite, ajouter une référence à cet auditeur:

private EditNameDialogListener listener;

ceci sera utilisé pour" activer " la(Les) méthode (s) d'écoute, et aussi pour vérifier si L'activité/Fragment parent implémente cette interface (voir ci-dessous).

dans le Activity / FragmentActivity / Fragment que "appelé" le DialogFragment simplement mettre en œuvre cette interface.

dans votre DialogFragment tout ce que vous devez ajouter au point où vous souhaitez rejeter le DialogFragment et retourner le résultat est ceci:

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

mEditText.getText().toString() est ce qui sera transmis à l'appel Activity .

notez que si vous voulez retourner quelque chose d'autre simplement changer les arguments auditeur prend.

enfin, vous devez 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.toString()
                + " must implement EditNameDialogListener");
    }
}

cette technique est très flexible et permet de rappeler avec le résultat même si votre don;t veulent rejeter le dialogue juste pour l'instant.

128
répondu Assaf Gamliel 2016-08-27 21:27:48

il y a une façon beaucoup plus simple de recevoir un résultat d'un fragment de dialogue.

tout D'abord, dans votre activité, Fragment ou activité de fragment, vous devez ajouter 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 étiquette int pour le DialogFragment que vous avez appelé, je vais montrer comment cela fonctionne dans une seconde. Le resultCode est le code que vous renvoyez depuis le DialogFragment et qui indique votre activité d'attente en cours., Fragment, ou Fragmentactivité ce qui s'est passé.

Le prochain morceau de code est l'appel à la 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 l'onActivityResult (...) une fois que la boîte de dialogue est désactivée, et vous montrez alors la boîte de dialogue. C'est aussi simple que cela.

maintenant, dans votre fragment de dialogue vous devez juste ajouter une ligne directement avant le dismiss() de sorte que vous renvoyez un résultatcode à onActivityResult().

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

C'est ça. Note, le code de résultat est défini comme int resultCode que j'ai mis à resultCode = 1; dans ce cas.

C'est tout, vous pouvez maintenant renvoyer le résultat de votre fragment de dialogue à votre activité d'appel, Fragment, ou FragmentActivity.

aussi, il semble que cette information a été affichée précédemment, mais il n'y avait pas d'exemple suffisant donné alors j'ai pensé que je pourrais fournir plus de détails.

EDIT 06.24.2016 Je m'excuse pour le code trompeur ci-dessus. Mais vous ne pouvez certainement pas recevoir le résultat de nouveau à l'activité vu que la ligne:

dialogFrag.setTargetFragment(this, 1);

fixe un objectif Fragment et non Activity . Donc, pour ce faire, vous devez utiliser un InterfaceCommunicator .

Dans votre DialogFragment définissez une variable globale

public InterfaceCommunicator interfaceCommunicator;

Créer une fonction publique à gérer

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

ensuite, lorsque vous êtes prêt à renvoyer le code au Activity lorsque le DialogFragment est exécuté, vous ajoutez simplement la ligne avant vous dismiss(); votre DialogFragment :

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

dans votre activité Maintenant vous devez faire deux choses, la première est de supprimer cette ligne de code qui n'est pas plus applicable:

dialogFrag.setTargetFragment(this, 1);  

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

public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator

puis @Override la fonction dans l'activité,

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

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

45
répondu Brandon 2016-06-24 13:05:37

il est peut-être trop tard pour répondre, Mais voici ce que j'ai fait pour obtenir les résultats du DialogFragment . très similaire à la réponse de @brandon. Ici j'appelle DialogFragment à partir d'un fragment, il suffit de placer ce code où vous appelez votre dialogue.

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 mise en œuvre de dialogfragment placez ce code où vous définissez vos données en intention. La valeur de resultCode est 1 vous pouvez le définir ou utiliser le système défini.

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

maintenant il est temps de revenir au fragment appelant et d'implémenter cette méthode. vérifiez la validité des données ou le succès du résultat si vous voulez avec resultCode et requestCode 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
        String myData = data.getStringExtra("listdata");
Toast.makeText(getActivity(),data.getStringExtra("listdata"),Toast.LENGTH_SHORT).show();
    }
16
répondu vikas kumar 2016-04-09 08:49:27

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

6
répondu Adil Hussain 2015-10-04 18:20:48

L'un des moyens faciles que j'ai trouvé était le suivant: Implémenter ceci est votre outil de dialogue,

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

et ensuite dans l'activité qui a appelé le Fragment de dialogue Créer la fonction appropriée en tant que telle:

 public void onUserSelectValue(String selectedValue) {

        // TODO add your implementation.
      Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show();
    }

le Toast est de montrer que ça marche. A travaillé pour moi.

6
répondu ZeWolfe15 2015-12-23 22:44:43

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 elle

public OnFragmentInteractionListener mCallback;

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

2) Fonte de l'activité pour l'mCallback variable dans le fragment

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

3) mettre en œuvre l'auditeur dans votre activité

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

4) outrepasser L'OnFragmentInteraction dans l'activité

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

Plus d'info sur lui: https://developer.android.com/training/basics/fragments/communicating.html

4
répondu lcompare 2017-07-30 19:00:39

dans mon cas, j'ai dû passer des arguments à un fragmentcible. Mais j'ai l'exception "Fragment déjà actif". J'ai donc déclaré une Interface dans mon DialogFragment que parentFragment implémentait. Lorsque parentFragment a commencé un DialogFragment , il s'est défini comme TargetFragment. Puis dans DialogFragment j'ai appelé

 ((Interface)getTargetFragment()).onSomething(selectedListPosition);
1
répondu Lanitka 2017-07-03 08:51:26

juste pour l'avoir comme une des options (puisque personne ne l'a mentionné encore) - vous pourriez utiliser un bus d'événement comme Otto. Donc dans le dialogue vous faites:

bus.post(new AnswerAvailableEvent(42));

et que votre interlocuteur (activité ou Fragment) y souscrive:

@Subscribe public void answerAvailable(AnswerAvailableEvent event) {
   // TODO: React to the event somehow!
}
-3
répondu Dennis K 2017-09-20 16:18:36