85

I am using a DialogFragment, and while I have successfully set an image to close (i.e. dismiss) the dialog when pressed, I am having a hard time finding the way to dismiss the dialog when the user clicks anywhere outside it, just as it works with normal dialogs. I thought there would be some sort of

dialogFragment.setCanceledOnTouchOutside(true);

call, but I don't see that in the documentation.

Is this possible with DialogFragment at all? Or am I looking in the wrong places? I tried intercepting touch events in the 'parent' activity but apart from not getting any touch event, it didn't seem right to me.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
sole
  • 2,057
  • 2
  • 17
  • 18

9 Answers9

191
DialogFragment.getDialog().setCanceledOnTouchOutside(true);

Must be called in onCreateView (as Apurv Gupta pointed out).

Dirk Jäckel
  • 2,979
  • 3
  • 29
  • 47
Hamed
  • 2,034
  • 1
  • 13
  • 4
59
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       ...
       getDialog().setCanceledOnTouchOutside(true);
       ... 
       }
manuzhang
  • 2,995
  • 4
  • 36
  • 67
21
    /** The system calls this only when creating the layout in a dialog. */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // The only reason you might override this method when using onCreateView() is
        // to modify any dialog characteristics. For example, the dialog includes a
        // title by default, but your custom layout might not need it. So here you can
        // remove the dialog title, but you must call the superclass to get the Dialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCanceledOnTouchOutside(true);

        return dialog;
    }
Yakiv Mospan
  • 8,174
  • 3
  • 31
  • 35
  • this didn't work for me. I had to call `setCanceledOnTouchOutside` in `onCreateView` as per @Apurv. I should mention that I called `setCanceledOnTouchOutside(false)` – kimbaudi Oct 23 '16 at 07:46
10

Lot of answers here but, the app crash when dialog opens. Writing getDialog().setCanceledOnTouchOutside(true); inside onCreateView did not work and crashed my app.

(I am using AppCompatActivity as my BaseActivity and android.app.DialogFragment as my Fragment).

What works is either of the two following lines:

getDialog().setCanceledOnTouchOutside(true);

OR

this.getDialog().setCanceledOnTouchOutside(true);

inside onActivityCreated like

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimationZoom;
        //getDialog().getWindow().setDimAmount(0.85f);
        getDialog().setCanceledOnTouchOutside(true);//See here is the code
    }

What not to use:

DialogFragment.getDialog().setCanceledOnTouchOutside(false);

throws following error

enter image description here

And writing the code in onCreateView crashes the App! Please update the answer if you find something wrong.

sud007
  • 5,824
  • 4
  • 56
  • 63
  • Probably this is because you create a dialog inside `onCreateDialog()`, where it is a usual way of initialization. In this case `onCreateView()` does nothing and even doesn't contain a view. You can try to move the code to `onCreateDialog()`. – CoolMind Apr 17 '19 at 08:07
  • @CoolMind Oh that's a nice observation. Will surely keep this in my try list. Thanks! – sud007 Apr 19 '19 at 07:56
  • 1
    I think, your answer, nevertheless, makes sence, and 4 people marked pluses. I also experienced problems with `onCreateDialog`, `onCreateView` in near past. Maybe I am wrong, and you should retain `onActivityCreated`, it is a nice method to make additional initialization (see https://stackoverflow.com/a/50734566/2914140, for example). – CoolMind Apr 19 '19 at 09:08
  • @CoolMind nice that works for you. But I can notice that, problems that you are experiencing are because of your `BottomSheet` implementation. It might be different in case of BSheet I agree. But this solution for a `DialogFragment` does work well. – sud007 Apr 22 '19 at 02:16
6

If you want to execute some logic when clicking outside of a DialogFragment, just override the onCancel method.

override fun onCancel(dialog: DialogInterface) {
    super.onCancel(dialog)
    // Do your work here
}
Thomas
  • 550
  • 5
  • 17
2

This works fine for Java:

DialogFragment.getDialog().setCanceledOnTouchOutside(false);
Boken
  • 4,825
  • 10
  • 32
  • 42
0

I would recommend to use my solution only after trying out above solutions. I have described my solution here. Just to brief, I am checking touch bounds of DialogFragment.getView(). When touch points are outside DialogFragment, I am dismissing the Dialog.

Community
  • 1
  • 1
Swaroop
  • 532
  • 1
  • 4
  • 16
0
            Dialog.SetCanceledOnTouchOutside(true);

Worked for me
My Code

class dlgRegister : DialogFragment
        {
    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
    ....
    ....
    }
    public override void OnActivityCreated(Bundle savedInstanceState)
            {
                Dialog.Window.RequestFeature(WindowFeatures.NoTitle);
                Dialog.SetCanceledOnTouchOutside(true);
                base.OnActivityCreated(savedInstanceState);
                Dialog.Window.Attributes.WindowAnimations =    Resource.Style.dialog_animation;
            }
    }
sham
  • 691
  • 8
  • 28
0
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup
container, @Nullable Bundle savedInstanceState) 
{
        DialogConfermationdialogBinding binding = DialogConfermationdialogBinding.inflate(inflater,container,false);
        View view = binding.getRoot();

        getDialog().setCanceledOnTouchOutside(false);

        return view;
}
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 05 '23 at 22:00