我已经为我的应用程序实现了一个自定义对话框。我希望在用户单击对话框外部时,对话框会被关闭。 我需要做什么才能实现这一功能?
我已经为我的应用程序实现了一个自定义对话框。我希望在用户单击对话框外部时,对话框会被关闭。 我需要做什么才能实现这一功能?
dialog.setCanceledOnTouchOutside(true);
来实现在对话框外部触摸时关闭对话框。像这样: Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
如果你的对话框不是模态的,则:
1 - 为你的对话框窗口属性设置标志FLAG_NOT_TOUCH_MODAL
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - 添加另一个标志到Windows属性,FLAG_WATCH_OUTSIDE_TOUCH
- 这个标志是为了让对话框可以接收其可见区域外的触摸事件。
3 - 重写对话框的onTouchEvent()
方法并检查动作类型。如果动作类型是'MotionEvent.ACTION_OUTSIDE
',表示用户正在对话框区域外进行交互。在这种情况下,您可以关闭对话框或决定您想要执行什么操作。
view plainprint?
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
this.dismiss();
}
return false;
}
如需了解更多信息,请查看如何基于触点取消自定义对话框?和如何在点击对话框区域外部时取消非模态对话框
只需要简单地使用
dialog.setCanceledOnTouchOutside(true);
@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 );
}
来源: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html
如果您正在使用在样式xml中定义的主题自定义对话框,请在您的主题中放置此行:
<item name="android:windowCloseOnTouchOutside">true</item>
dialog.setCanceledOnTouchOutside(true);
非常有效。 - doplumidialog.setCanceledOnTouchOutside(true);
在触摸对话框外部时关闭它。
如果您不想在触摸对话框外部关闭它,请使用以下代码:
dialog.setCanceledOnTouchOutside(false);
如果您有以下代码,请删除它,这个方法应该完全避免获取灰色区域下面的点击事件。
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
@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);
}
AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);
或者
alertDialog.setCancelable(true);
如果你拥有一个AlertDialog.Builder
,那么你可以尝试以下方法:
alertDialogBuilder.setCancelable(true);
这段代码用于在用户点击对话框时隐藏键盘输入法,在用户点击对话框外部时,同时关闭软键盘输入法和对话框。
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;
}
};
Window
的安卓源代码。
你只需将这两个方法添加到对话框源代码中即可。@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));
}
这个解决方案没有这个问题:
这个方法很好,但是底层的活动也会对触摸事件做出反应。有什么办法可以防止这种情况发生吗?- howettl
以下方法对我有效:
myDialog.setCanceledOnTouchOutside(true);