How to dismiss the dialog with click on outside of the dialog?

AndroidAndroid LayoutAndroid EmulatorDialogAndroid Dialog

Android Problem Overview


I have implemented a custom dialog for my application. I want to implement that when the user clicks outside the dialog, the dialog will be dismissed. What do I have to do for this?

Android Solutions


Solution 1 - Android

You can use dialog.setCanceledOnTouchOutside(true); which will close the dialog if you touch outside of the dialog.

Something like,

  Dialog dialog = new Dialog(context)
  dialog.setCanceledOnTouchOutside(true);

Or if your Dialog in non-model then,

1 - Set the flag-FLAG_NOT_TOUCH_MODAL for your dialog's window attribute

Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

2 - Add another flag to windows properties,, FLAG_WATCH_OUTSIDE_TOUCH - this one is for dialog to receive touch event outside its visible region.

3 - Override onTouchEvent() of dialog and check for action type. if the action type is 'MotionEvent.ACTION_OUTSIDE' means, user is interacting outside the dialog region. So in this case, you can dimiss your dialog or decide what you wanted to perform. view plainprint?

public boolean onTouchEvent(MotionEvent event)  
{  
   
       if(event.getAction() == MotionEvent.ACTION_OUTSIDE){  
        System.out.println("TOuch outside the dialog ******************** ");  
               this.dismiss();  
       }  
       return false;  
}  

For more info look at How to dismiss a custom dialog based on touch points? and How to dismiss your non-modal dialog, when touched outside dialog region

Solution 2 - Android

Simply use

dialog.setCanceledOnTouchOutside(true);

Solution 3 - Android

You can use this implementation of onTouchEvent. It prevent from reacting underneath activity to the touch event (as mentioned howettl).

@Override
public boolean onTouchEvent ( MotionEvent event ) {
  // I only care if the event is an UP action
  if ( event.getAction () == MotionEvent.ACTION_UP ) {
    // create a rect for storing the window rect
    Rect r = new Rect ( 0, 0, 0, 0 );
    // retrieve the windows rect
    this.getWindow ().getDecorView ().getHitRect ( r );
    // check if the event position is inside the window rect
    boolean intersects = r.contains ( (int) event.getX (), (int) event.getY () );
    // if the event is not inside then we can close the activity
    if ( !intersects ) {
      // close the activity
      this.finish ();
      // notify that we consumed this event
      return true;
    }
  }
  // let the system handle the event
  return super.onTouchEvent ( event );
}

Source: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html

Solution 4 - Android

Or, if you're customizing the dialog using a theme defined in your style xml, put this line in your theme:

<item name="android:windowCloseOnTouchOutside">true</item>

Solution 5 - Android

dialog.setCanceledOnTouchOutside(true); 

to close dialog on touch outside.

And if you don't want to close on touch outside, use the code below:

dialog.setCanceledOnTouchOutside(false);

Solution 6 - Android

This method should completely avoid activities below the grey area retrieving click events.

Remove this line if you have it:

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

Put this on your activity created

getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

then override the touch event with this

@Override
public boolean onTouchEvent(MotionEvent ev)
{
	if(MotionEvent.ACTION_DOWN == ev.getAction())
	{
		Rect dialogBounds = new Rect();
	    getWindow().getDecorView().getHitRect(dialogBounds);
		if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
	        // You have clicked the grey area
			displayYourDialog();
	        return false; // stop activity closing
	    }
	}

    // Touch events inside are fine.
	return super.onTouchEvent(ev);
}

Solution 7 - Android

You can try this :-

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

or

alertDialog.setCancelable(true);

And if you have a AlterDialog.Builder Then you can try this:-

alertDialogBuilder.setCancelable(true);
    

Solution 8 - Android

This code is use for when use click on dialogbox that time hidesoftinput and when user click outer side of dialogbox that time both softinput and dialogbox are close.

dialog = new Dialog(act) {
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// Tap anywhere to close dialog.
		Rect dialogBounds = new Rect();
		getWindow().getDecorView().getHitRect(dialogBounds);
		if (!dialogBounds.contains((int) event.getX(),
				(int) event.getY())) {
			// You have clicked the grey area
			InputMethodManager inputMethodManager = (InputMethodManager) act
					.getSystemService(act.INPUT_METHOD_SERVICE);
			inputMethodManager.hideSoftInputFromWindow(dialog
					.getCurrentFocus().getWindowToken(), 0);
			dialog.dismiss();
			// stop activity closing
		} else {
			InputMethodManager inputMethodManager = (InputMethodManager) act
					.getSystemService(act.INPUT_METHOD_SERVICE);
			inputMethodManager.hideSoftInputFromWindow(dialog
					.getCurrentFocus().getWindowToken(), 0);
		}

		return true;
	}
};

Solution 9 - Android

Another solution, this code was taken from android source code of Window You should just add these Two methods to your dialog source code.

@Override
public boolean onTouchEvent(MotionEvent event) {		
	if (isShowing() && (event.getAction() == MotionEvent.ACTION_DOWN
            && isOutOfBounds(getContext(), event) && getWindow().peekDecorView() != null)) {
		hide();
	}
	return false;
}

private boolean isOutOfBounds(Context context, MotionEvent event) {
    final int x = (int) event.getX();
    final int y = (int) event.getY();
    final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
    final View decorView = getWindow().getDecorView();
    return (x < -slop) || (y < -slop)
            || (x > (decorView.getWidth()+slop))
            || (y > (decorView.getHeight()+slop));
}

This solution doesnt have this problem : > This works great except that the activity underneath also reacts to the touch event. Is there some way to prevent this? – howettl

Solution 10 - Android

Following has worked for me:

myDialog.setCanceledOnTouchOutside(true);

Solution 11 - Android

Call dialog.setCancelable(false); from your activity/fragment.

Solution 12 - Android

You can make a background occupying all the screen size transparent and listen to the onClick event to dismiss it.

Solution 13 - Android

I tried some answers still I faced a problem like when I press outside the dialog dialog was hiding but a dimmed view was showing, and pressing again would go to the parent activity. But actually I wanted to go the parent activity after first click. So what I did was

dialog.setOnCancelListener(this);

and changed my activity to implement DialogInterface.OnCancelListener with

@Override
public void onCancel(DialogInterface dialog) {
     finish();
}

And boom, it worked.

Solution 14 - Android

Here is the code

    dialog.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {

            if(MotionEvent.ACTION_DOWN == ev.getAction())
            {
                Rect dialogBounds = new Rect();
                dialog. getWindow().getDecorView().getHitRect(dialogBounds);
                if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
                    // You have clicked the grey area
                    UiUtils.hideKeyboard2(getActivity());
                    return false; // stop activity closing
                }
            }
            getActivity().dispatchTouchEvent(ev);
            return false;
        }
    });

Try this one . you can hide the keyboard when you touch outside

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShreyash MahajanView Question on Stackoverflow
Solution 1 - Androiduser370305View Answer on Stackoverflow
Solution 2 - AndroidEbin SebastianView Answer on Stackoverflow
Solution 3 - AndroidLukas NovakView Answer on Stackoverflow
Solution 4 - AndroidChris.ZouView Answer on Stackoverflow
Solution 5 - AndroidNaveenView Answer on Stackoverflow
Solution 6 - AndroidUnknownweirdoView Answer on Stackoverflow
Solution 7 - AndroidJulfikarView Answer on Stackoverflow
Solution 8 - AndroidMaulik SantokiView Answer on Stackoverflow
Solution 9 - AndroidRoman NazarevychView Answer on Stackoverflow
Solution 10 - AndroidAkanshi SrivastavaView Answer on Stackoverflow
Solution 11 - AndroidEKNView Answer on Stackoverflow
Solution 12 - AndroidoriolponsView Answer on Stackoverflow
Solution 13 - AndroidSodrul Amin ShaonView Answer on Stackoverflow
Solution 14 - AndroidSaljith KjView Answer on Stackoverflow