web-dev-qa-db-fra.com

DialogFragment et onDismiss

J'utilise une DialogFragment, que je montre comme ceci à partir d'une Activity:

DialogFragmentImage dialog = DialogFragmentImage.newInstance(createBitmap());
dialog.onDismiss(dialog);.onDismiss(this);          
dialog.show(getFragmentManager(), "DialogFragmentImage");

Je voudrais vérifier quand la DialogFragment a été rejetée (par exemple, lorsque le bouton de retour a été enfoncé), mais dans ma Activity. Comment puis je faire ça? Comment puis-je "dire" à ma activity que la DialogFragment a été congédiée?

45
deimos1988

Faites en sorte que votre activité implémente OnDismissListener

public final class YourActivity extends Activity implements DialogInterface.OnDismissListener {

    @Override
    public void onDismiss(final DialogInterface dialog) {
        //Fragment dialog had been dismissed
    }

}

DialogFragment implémente déjà OnDismissListener, il suffit de remplacer la méthode et d'appeler l'activité.

public final class DialogFragmentImage extends DialogFragment {

    ///blah blah

    @Override
    public void onDismiss(final DialogInterface dialog) {
        super.onDismiss(dialog);
        final Activity activity = getActivity();
        if (activity instanceof DialogInterface.OnDismissListener) {
            ((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
        }
    }

}

Si vous démarrez la boîte de dialogue à partir d'un fragment à l'aide du gestionnaire childFragment (API> = 17), vous pouvez utiliser getParentFragment pour parler à onDismissListener sur le fragment parent.

public final class DialogFragmentImage extends DialogFragment {

    ///blah blah

    @Override
    public void onDismiss(final DialogInterface dialog) {
        super.onDismiss(dialog);
        Fragment parentFragment = getParentFragment();
        if (parentFragment instanceof DialogInterface.OnDismissListener) {
            ((DialogInterface.OnDismissListener) parentFragment).onDismiss(dialog);
        } 
    }

}
81

Voici ma réponse. C'est un peu tard, mais c'est peut-être avantageux pour quelqu'un qui passe. 

FragmentManager fm = getFragmentManager();

YourDialogFragment dialog = new YourDialogFragment();
dialog.show(fm,"MyDialog");

fm.executePendingTransactions();
dialog.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialogInterface) {
                       //do whatever you want when dialog is dismissed
                    }
                });

Nous devons appeler 

fm.executePendingTransactions(); 

Pour vous assurer que le travail FragmentTransaction a été effectué. Sinon, NullPointerException peut survenir lorsque vous appelez setOnDismissListener().

Désolé s'il y a une erreur. J'espère que cette aide.

15
Boonya Kitpitak

Réponse alternative, si vous n'avez pas accès à la méthode onDismiss of activity.

//DIALOGFRAGMENT
//Create interface in your DialogFragment (or a new file)
public interface OnDismissListener {
   void onDismiss(MyDialogFragment myDialogFragment);
}
//create Pointer and setter to it
private OnDismissListener onDismissListener;
public void setDissmissListener(DissmissListener dissmissListener) {
   this.dissmissListener = dissmissListener;
}
//Call it on the dialogFragment onDissmiss
@Override
public void onDismiss(DialogInterface dialog) {
   super.onDismiss(dialog);

   if (onDismissListener != null) {
      onDismissListener.onDismiss(this);
   }
}

//OTHER CLASS, start fragment where you want
MyDialogFragment df = new MyDialogFragment();
df.setOnDismissListener(new MyDialogFragment.OnDismissListener() {
   @Override
   public void onDismiss(MyDialogFragment myDialogFragment) {
      //Call when MyDialogFragment close
   }
});
df.show(activity.getFragmentManager(), "myDialogFragment");

edit: si le système a besoin de recréer DialogFragment: .__

MyDialogFragment myDialogFragment = getFragmentManager().findFragmentByTag("MyDialogFragment"); 
if(myDialogFragment != null) { 
   myDialogFragment.setOnDismissListener(...); 
}
4
Anthone

C'est un vieux problème, mais je n'ai trouvé aucune solution avec laquelle je suis heureux. Je n'aime pas faire passer un écouteur à mon DialogFragment ou définir un TargetFragment, car cela pourrait casser lors du changement d'orientation. Que pensez-vous de ceci? 

        MyDialog d = new MyDialog();
        d.show(fragmentManager, "tag");
        fragmentManager.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {
            @Override
            public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {
                super.onFragmentViewDestroyed(fm, f);
                //do sth      
        fragmentManager.unregisterFragmentLifecycleCallbacks(this);
                }
            }, false);
4
Kaskasi
public class OpcoesProdutoDialogo extends DialogFragment{
    private DialogInterface.OnDismissListener onDismissOuvinte;
.
.
.

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

    public void setOnDismissListener(@Nullable DialogInterface.OnDismissListener listener) {
        this.onDismissOuvinte = listener;
    }
}

et en appel

OpcoesProdutoDialogo opcProduto = OpcoesProdutoDialogo.criar(itemPedido);
        opcProduto.show(getFragmentManager(), "opc_produto_editar");
        opcProduto.setOnDismissListener(d->{
            adapterItens.notifyItemChanged(posicao);
        });
1
user3795295

Si vous n'aimez pas la solution de @ yaroslav-mytkalyk, dans laquelle le fragment doit convertir le fragment activité/parent, en voici un autre:

Voici l'idée:

  1. Exposez un auditeur dans votre fragment, DialogFragmentImage.
  2. Implémentez l'écouteur dans votre activité et transmettez-le au fragment lors de sa création. Assurez-vous également d'utiliser une balise pour pouvoir retrouver le fragment ultérieurement (lisez ci-dessous).
  3. Dans onStop(), supprimez l'auditeur afin de ne pas laisser l'activité fuir si elle est détruite. Cela se produira lors de la rotation de l'écran, car l'activité sera recréée.
  4. Dans onResume(), vérifiez si le fragment existe et si oui, rajoutez l'écouteur.

Exposez un auditeur de votre fragment:

class MyFragment extends DialogFragment {

    public interface OnDismissListener {
        void dismissed();
    }

    @Nullable
    private OnDismissListener onDismissListener;

    public void setOnDismissListener(@Nullable OnDismissListener onDismissListener) {
        this.onDismissListener = onDismissListener;
    }

    /*
    If you are calling dismiss() or dismissAllowingStateLoss() manually,
    don't forget to call:
    if (onDismissListener != null) {
        onDismissListener.dismissed();
    }

    Otherwise, override them and call it there.
    */
}

Et voici à quoi votre activité devrait ressembler:

class MyActivity extends AppCompatActivity {

    private static final String MY_FRAGMENT_TAG = "my_fragment";

    private MyFragment.OnDismissListener myFragmentListener = () -> {

        // ...
    };

    /**
     * Shows the fragment. Note that:
     * 1. We pass a tag to `show()`.
     * 2. We set the listener on the fragment.
     */
    private void showFragment() {

        MyFragment fragment = new MyFragment();
        fragment.show(getSupportFragmentManager(), MY_FRAGMENT_TAG);
        fragment.setOnDismissListener(myFragmentListener);
    }

    @Override
    protected void onStart() {

        super.onStart();

        // Restore the listener that we may have removed in `onStop()`.
        @Nullable MyFragment myFragment =  (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
        if (myFragment != null) {
            myFragment.setOnDismissListener(myFragmentListener);
        }
    }

    @Override
    protected void onStop() {

        // If the fragment is currently shown, remove the listener so that the activity is not leaked when e.g. the screen is rotated and it's re-created.
        @Nullable MyFragment myFragment =  (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
        if (myFragment != null) {
            myFragment.setOnDismissListener(null);
        }

        super.onStop();
    }
}
0
Minas Mina