web-dev-qa-db-fra.com

Rappel lorsque DialogFragment est rejeté

Je souhaite lancer une boîte de dialogue avec une mise en page personnalisée, que j'ai implémentée via un DialogFragment. (Je viens de changer onCreateView () et d’ajouter des gestionnaires de boutons) La boîte de dialogue permet à l'utilisateur de modifier rapidement un paramètre important.

Cette boîte de dialogue sera lancée à partir de plusieurs activités différentes. Les différentes activités n'ont pas grand-chose en commun, sauf qu'elles doivent être actualisées après que l'utilisateur a modifié le paramètre. Ils n'ont pas besoin d'obtenir d'informations du dialogue. ils ont simplement besoin de savoir quand il est fermé (licencié).

Ce que j'ai essayé

J'ai essayé d'avoir l'actualisation de l'activité dans onResume (), mais lancer et fermer une boîte de dialogue ne semble jamais appeler cette méthode. (Je ne suis donc pas sûr de savoir pourquoi cela existe, mais c'est probablement un sujet pour une autre question.)

Ensuite, j'ai essayé d'ajouter un DialogInterface.OnDismissListener à la boîte de dialogue:

public static void showMyDialog(OnDismissListener listener, Activity activity)
{
    DialogFragment fragment = new MyDialogFragment();
    fragment.show(activity.getFragmentManager(), "date");
    activity.getFragmentManager().executePendingTransactions();//A
    fragment.getDialog().setOnDismissListener(listener);//B
}

Lorsque j'ai initialement omis la ligne A, j'ai eu une exception NullPointerException sur la ligne B car la boîte de dialogue est nulle à ce stade. Suivant l’avis de cette SO réponse , j’ai lancé l’appel à executePendingTransaction (). Cela provoque une exception IllegalStateException sur la ligne B, avec le message "OnDismissListener est déjà utilisé par DialogFragment et ne peut pas être remplacé". J'ai également essayé de mettre setOnDismissListener () avant l'appel à show (), mais cela provoquait toujours une exception NullPointerException.

J'ai ensuite lu cette autre SO réponse , qui indique que le demandeur d'origine "avait appelé getDialog () trop tôt dans le cycle de vie de DialogFragment". J'ai donc essayé d'ajouter un constructeur à mon DialogFragment:

public MyDialogFragment(SomeCallback illTakeAnythingICanGet)
{
    //I'll store the callback here and call it later
}

Malheureusement, l'ajout d'un constructeur à Android Lint paniqué avec un avertissement fatal, et lorsque j'ai cherché, j'ai trouvé un commentaire dans cette question qui semble dire que cette approche rendra impossible la gestion de la rotation de l'utilisateur l'écran pendant que la boîte de dialogue est ouverte.

La question

Comment une activité peut-elle déterminer quand un DialogFragment s'est fermé (a été congédié) de manière à ne pas endommager mon application si l'utilisateur fait pivoter l'écran? Devrais-je utiliser autre chose qu'un DialogFragment?

17
Impatient Dev

Ceci est juste une explication plus longue du commentaire du harisme au cas où quelqu'un d'autre aurait le même problème que moi.

Vous pouvez accomplir ce que je voulais en créant une interface comme celle-ci:

public interface MyDialogCloseListener
{
    public void handleDialogClose(DialogInterface dialog);//or whatever args you want
}

Demandez à l'activité qui lance votre dialogue (DialogFragment) d'implémenter cette interface. Ensuite, donnez à DialogFragment la méthode suivante:

public void onDismiss(DialogInterface dialog)
{
    Activity activity = getActivity();
    if(activity instanceof MyDialogCloseListener)
        ((MyDialogCloseListener)activity).handleDialogClose(dialog);
}
29
Impatient Dev

Plus de code explicatif pour que quelqu'un fasse la même chose.

Créez la interface comme:

package com.example.dialoglistener;
import Android.content.DialogInterface;

public interface MyDialogCloseListener {
    public void handleDialogClose(DialogInterface dialog);
}

Implémenter l'interface en activité en tant que:

MyDialogCloseListener closeListener = new MyDialogCloseListener() {
        @Override
        public void handleDialogClose(DialogInterface dialog) {                                     
            //do here whatever you want to do on Dialog dismiss
        }
};

Ecrire une DismissListener dans DialogFragement comme

public void DismissListener(MyDialogCloseListener closeListener) {
        this.closeListener = closeListener;
}

appelez DismissListener de votre activité en tant que:

dialogFragementObject.DismissListener(closeListener);

et enfin écrire la méthode onDismiss

@Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if(closeListener != null) {
            closeListener.handleDialogClose(null);
        }

    }
13
shaby

L'exemple de Tyler était le seul exemple que je pouvais trouver qui fonctionnait réellement. L'appel de la méthode DismissListner dans la classe DialogFragment est la seule chose à modifier pour que l'exemple fonctionne. Il l'a comme: 

dialogFragementObject.DismissListner(closeListener);

Cela doit simplement être un transtypage pour le nom de classe de ce DialogFragment. Par exemple: 

((MyDialogFragment)dialogFragementObject).DismissListner(closeListener);
0
user3199522