[android] How to correctly dismiss a DialogFragment?

The docs say this for the dismiss() method from the Dialog class:

Dismiss this dialog, removing it from the screen. This method can be invoked safely from any thread. Note that you should not override this method to do cleanup when the dialog is dismissed, instead implement that in onStop().

In my code, all I do is call getDialog().dismiss() to dismiss it. But I am not doing anything else or even using onStop(). So I am asking exactly how to correctly dismiss a DialogFragment to avoid any memory leaks, etc..

This question is related to android android-dialogfragment

The answer is


I gave an upvote to Terel's answer. I just wanted to post this for any Kotlin users:

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}

You should dismiss you Dialog in onPause() so override it.

Also before dismissing you can check for null and is showing like below snippet:

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}

I think a better way to close a DialogFragment is this:

Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
    DialogFragment df = (DialogFragment) prev;
    df.dismiss();
}

This way you dont have to hold a reference to the DialogFragment and can close it from everywhere.


There are references to the official docs (DialogFragment Reference) in other answers, but no mention of the example given there:

void showDialog() {
    mStackLevel++;

    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
    newFragment.show(ft, "dialog");
}

This removes any currently shown dialog, creates a new DialogFragment with an argument, and shows it as a new state on the back stack. When the transaction is popped, the current DialogFragment and its Dialog will be destroyed, and the previous one (if any) re-shown. Note that in this case DialogFragment will take care of popping the transaction of the Dialog is dismissed separately from it.

For my needs I changed it to:

FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
    manager.beginTransaction().remove(prev).commit();
}

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);

Adding to the other answers, when having a DialogFragment that is full screen calling dismiss() won't pop the DialogFragment from the fragment backstack. A workaround is to call onBackPressed() on the parent activity.

Something like this:

CustomDialogFragment.kt

closeButton.onClick {
    requireActivity().onBackPressed()
}

Kotlin Version of Terel answer

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()

I found that when my fragment was defined in the navigation graph with a <fragment> tag (for a full screen dialogfragment), the dialogfragment would not dismiss with the dismiss() command. Instead, I had to pop the back stack:

findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();

However, if the same dialogfragment was defined in the navigation graph with a <dialog> tag, dismiss() works fine.


Just call dismiss() from the fragment you want to dismiss.

imageView3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });

CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
  dialog.dismiss();
}

Consider the below sample code snippet which demonstrates how to dismiss a dialog fragment safely:

DialogFragment dialogFragment = new DialogFragment();

/** 
 * do something
 */

// Now you want to dismiss the dialog fragment
if (dialogFragment.getDialog() != null && dialogFragment.getDialog().isShowing())
{
    // Dismiss the dialog
    dialogFragment.dismiss();
}

Happy Coding!


Here is a simple AppCompatActivity extension function, which closes opened Dialog Fragment:

fun AppCompatActivity.whenDialogOpenDismiss(
    tag: String
) {
    supportFragmentManager.findFragmentByTag(tag)?.let { 
        if(it is DialogFragment) it.dismiss() }
}

Of course you can call it from any activity directly. If you need to call it from a Fragment just make the same extension function about Fragment class


Why don't you try using only this code:

dismiss();

If you want to dismiss the Dialog Fragment by its own. You can simply put this code inside the dialog fragment where you want to dismiss the Dialog.

For example:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});

This will close the recent Dialog Fragment that is shown on the screen.

Hope it helps for you.