How to correctly dismiss a DialogFragment?

不想你离开。 提交于 2019-11-27 05:02:32

问题


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..


回答1:


tl;dr: The correct way to close a DialogFragment is to use dismiss() directly on the DialogFragment.


Details: The documentation of DialogFragment states

Control of the dialog (deciding when to show, hide, dismiss it) should be done through the API here, not with direct calls on the dialog.

Thus, you should not use getDialog().dismiss(), since that would invoke dismiss() on the dialog. Instead, you should use the dismiss() method of the DialogFragment itself:

public void dismiss()

Dismiss the fragment and its dialog. If the fragment was added to the back stack, all back stack state up to and including this entry will be popped. Otherwise, a new transaction will be committed to remove the fragment.

As you can see, this takes care not only of closing the dialog but also of handling the fragment transactions involved in the process.

You only need to use onStop if you explicitly created any resources that require manual cleanup (closing files, closing cursors, etc.). Even then, I would override onStop of the DialogFragment rather than onStop of the underlying Dialog.




回答2:


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.




回答3:


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()
}



回答4:


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.




回答5:


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();
    }
}



回答6:


Kotlin Version of Terel answer

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



回答7:


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);



回答8:


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

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


来源:https://stackoverflow.com/questions/11201022/how-to-correctly-dismiss-a-dialogfragment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!