Allow outside touch for DialogFragment

I have found alternative way to handle dismiss on touch outside. Please check below code sample, that would definitely work,

@Override
public void onStart() {
    // mDialogView is member variable
    mDialogView = getView();
    mDialogView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            float eventX = event.getRawX();
            float eventY = event.getRawY();

            int location[] = new int[2];
            mDialogView.getLocationOnScreen(location);

            if (eventX < location[0] || eventX > (location[0] + mDialogView.getWidth()) || eventY < location[1]
                    || eventY > location[1] + mDialogView.getHeight()) {
                dismiss();
                return true;
            }
            return false;
        }
    });
}

In my case, I was getting getDialog() as not null value, but getDialog().dismiss() was not working. Also, the solution that is marked as right above, also did not work in my case. So, I took this approach.


In order to do that, a flag of the Window that allows the outside touch should be turned on and for the good appearance the background dim flag should be cleared.
Since it must be done after dialog is created, I've implemented it via the Handler.

@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // This is done in a post() since the dialog must be drawn before locating.
    getView().post(new Runnable() {

        @Override
        public void run() {

            Window dialogWindow = getDialog().getWindow();

            // Make the dialog possible to be outside touch
            dialogWindow.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
            dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

            getView().invalidate();
        }
    });
}

At this moment the outside touch is possible.

In case we want to make it nicer and without the frame, the following code can be added:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Hide title of the dialog
    setStyle(STYLE_NO_FRAME, 0);
}

@yaniv has provided the answer. But in case you want, here's a snippet where you get the same result but withou the need to post a Runnable to the root View:

@NonNull
@Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
    return dialog;
}

This is more generic flag to allow any action not only touch actions

window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);