如何在对话框外单击对话框来closures对话框?

我为我的应用程序实现了一个自定义对话框。 我想实现,当用户点击对话框外,对话框将被解雇。 我该怎么做呢?

你可以使用dialog.setCanceledOnTouchOutside(true); 如果您在对话框之外触摸,将会closures对话框。

就像是,

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

或者如果你的Dialog在非模式的话,

1 – 为对话框的窗口属性设置FLAG_NOT_TOUCH_MODAL标志

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

2 – 将另一个标志添加到窗口属性, FLAG_WATCH_OUTSIDE_TOUCH – 这是一个对话框来接收可见区域外的触摸事件。

3 – 覆盖对话框的onTouchEvent()并检查操作types。 如果动作types为“ MotionEvent.ACTION_OUTSIDE ”,则意味着用户正在对话区域之外进行交互。 所以在这种情况下,您可以减less对话或决定要执行的操作。 查看文本打印

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

有关更多信息,请参阅如何根据触摸点取消自定义对话框? 以及如何在对话框区域之外触摸时消除非modal dialog

你可以使用onTouchEvent的这个实现。 它防止在触摸事件之下的活动(如提到的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 ); } 

资料来源: http : //blog.twimager.com/2010/08/closing-activity-by-touching-outside.html

简单的使用

 dialog.setCanceledOnTouchOutside(true); 

或者,如果您使用样式xml中定义的主题自定义对话框,请将此行放在主题中:

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

dialog.setCanceledOnTouchOutside(真);

closures外部对话

如果你不想在外面接触,请使用下面的内容

dialog.setCanceledOnTouchOutside(假);

这种方法应该完全避免在灰色区域下面的活动检索点击事件。

删除这条线,如果你有它:

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

把这个放在你创build的活动上

 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); } 

这个代码的另一个解决scheme是从Android的源代码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)); } 

这个解决scheme没有这个问题:

除了下面的活动也对触摸事件做出反应之外,这个工作很好。 有什么办法来防止这种情况? – howettl

你可以试试这个:

 AlterDialog alterdialog; alertDialog.setCanceledOnTouchOutside(true); 

要么

 alertDialog.setCancelable(true); 

如果你有一个AlterDialog.Builder那么你可以试试这个:

 alertDialogBuilder.setCancelable(true); 

此代码用于当用户点击时间隐藏的对话框和当用户点击对话框的外侧时,softinput和dialogbox接近的时候……

  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; } }; 

您可以使background占用所有屏幕尺寸transparent并听取onClick事件来dismiss它。

调用dialog.setCancelable(false); 从你的活动/片段