Tap outside Android dialog to dismiss it?
Solution 1
My app is a single activity with Theme.Holo.Dialog. In my case the other answer did not work. It only made the other background apps or the launch screen to receive touch events.
I found that using dispatchTouchEvent works in my case. I think it is also a simpler solution. Here's some sample code on how to use it to detect taps outside the activity with a Dialog theme:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// Tapped outside so we finish the activity
this.finish();
}
return super.dispatchTouchEvent(ev);
}
Solution 2
dialog.setCanceledOnTouchOutside(true)
Sets whether this dialog is canceled when touched outside the window's bounds.
Solution 3
There is a TouchInterceptor
method which will called when you touch on out side of popup window
For example
mWindow.setTouchInterceptor(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mWindow.dismiss();
return true;
}
return false;
}
});
mWindow
is the popup window
And if you want same functionality for Activity you have to follow below steps.
1) Add flag before setContentView()
method called in onCreate();
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
2) Override onTouchEvent()
event in Activity
and write below code
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Finish", 3000).show();
finish();
return true;
}
return false;
}
The complete copy is here
Activity
package net.londatiga.android;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.Toast;
public class NewQuickAction3DActivity extends Activity implements OnTouchListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make us non-modal, so that others can receive touch events.
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
setContentView(R.layout.main);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Hi", 3000).show();
return true;
}
return false;
}
}
This is manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.londatiga.android"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".NewQuickAction3DActivity"
android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Dialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Solution 4
You may use
dialog.setCancelable(true\false);
For the lastest vesrions of Android;
It will disable outSideTouching event.
Solution 5
You could use Activity#setFinishOnTouchOutside too, if your dialog is an Activity
. That's gotta be the shortest way for Activity
s ;)
(It's API 11+ though. But API <= 10 is generally screen size normal.)
Comments
-
Michell Bak over 4 years
I was wondering if it's possible to somehow tap outside a popup dialog (or an Activity with a dialog theme), and dismiss it by just tapping outside of it?
I made a quick picture to illustrate it:
Normally, you have to press the back key to dismiss the dialogs, but on Honeycomb it could be great to have the option of just tapping outside the dialog, due to all the screen estate.
-
Michell Bak over 12 yearsThis is for
PopupWindow
only, right? I'm using a standard Activity with the Theme.Holo.Dialog theme in Honeycomb. -
Michell Bak over 12 yearsYeah, I tried it before you wrote it, but it didn't work either :( Missing a semicolon on finish() btw :)
-
Michell Bak over 12 yearsUsing Theme.Holo.Dialog? Remember, this is Honeycomb.
-
Dharmendra over 12 yearsIf you want to test in small screen just set theme of activity as dialog and click outside it will give you message.
-
Michell Bak over 12 yearsI'm using a Honeycomb tablet, and I'm starting an activity with Theme.Holo.Dialog from another activity, and pressing outside the activity dialog bounds doesn't work.
-
Dharmendra over 12 yearsYes I had test in Honeycomb tablet emulator using Theme.Holo.Dialog and it is working fine for me
-
Michell Bak over 12 yearsDid you set the theme in the manifest.xml file? That's where I set it.
-
Michell Bak over 12 yearsYeah, that works - but I don't want the background activity to receive touch events. I have some buttons in the background activity that shouldn't be triggered. I guess I could just disable it upon starting the popup intent, but if there's an easier way, I'd definitely prefer that.
-
Dharmendra over 12 yearsCan you come in chat room "Android Discussion" ?
-
Michell Bak over 12 years@Dharmendra let us continue this discussion in chat
-
Glitch over 12 yearsThis works better if you change the if condition to
if (!dialogBounds.contains((int) event.getX(), (int) event.getY()) && event.getAction() == MotionEvent.ACTION_DOWN)
That way it doesn't close if the user accidentally moves their finger outside theActivity
. -
Ryan R over 12 yearsThis is the best solution...So simple. Why isn't this the answer?
-
Michell Bak over 12 yearsI needed it to work on an Activity with the dialog theme, and this won't work in that case, but I've upvoted it for general dialogs.
-
Jorge over 11 yearsUsing API level 8, Using an activity with theme
android:Theme.Dialog
and with this code:dialogBounds.top
anddialogBounds.left
have the value 0; anddialogBounds.bottom
anddialogBounds.right
have the values of the screen size, suggesting that the diolog window is actually assumed as full screen. So I can't put this code to work. Any other ideas why this is happening? -
Amt87 over 10 yearsIt is tested for all versions except KITKAT :)
-
Nick about 10 years
this.setFinishOnTouchOutside(false);
works for a Dialog Activity -
Pang about 10 yearsNo such method in
AlertDialog.Builder
, me not happy. -
Jacek Kwiecień about 10 yearsThis pretty much work, the problem is when I touch outside I also interact with the UI elements of the activity below which is bad.
-
Jacek Kwiecień about 10 yearsHere I posted the complete solution: stackoverflow.com/questions/23126701/…
-
suja about 10 years@Pang for
AlertDialog.Builder
tryalertBox.setCancelable(false);
-
ForceMagic almost 10 years@Pang @Xylian
SetCanceledOnTouchOutside
is a function that can be called on the AlertDialog returned byAlertDialog.Builder(activity).Create()
its not not on the builder itself. -
Oubaida AlQuraan about 9 years@Pang you can set the AlertDialog.Builder in Dialog reference like : Dialog dia = new AlertDialog.Builder(this) and use dia to use SetCanceledOnTouchOutside method
-
JaredBanyard about 8 yearsThis is the winning answer, the question is addressing Activities themed as Dialogs, not Dialogs.
-
gotwo over 4 yearsFor dismiss use the
true
value:this.setFinishOnTouchOutside(true);
This method is needed for the dialog activity but not for pure dialog.