Как закрыть диалоговое окно с щелчком на вне диалога?
я реализовал пользовательский диалог для моего приложения. Я хочу реализовать это, когда пользователь нажимает вне диалогового окна, диалог будет отклонен. Что я должен сделать для этого?
11 ответов:
можно использовать
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
' означает, что пользователь взаимодействует вне диалогового области. Таким образом, в этом случае вы можете dimiss свой диалог или решить, что вы хотели выполнить. посмотреть plainprint?public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_OUTSIDE){ System.out.println("TOuch outside the dialog ******************** "); this.dismiss(); } return false; }
для получения дополнительной информации смотрите на как закрыть пользовательский диалог на основе точек касания? и как закрыть ваш немодальный диалог, при прикосновении вне области диалога
вы можете использовать эту реализацию 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
или, если вы настраиваете диалог, используя тему, определенную в вашем стиле xml, поместите эту строку в свою тему:
<item name="android:windowCloseOnTouchOutside">true</item>
dialog.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);
и если у вас есть
AlterDialog.Builder
затем вы можете попробовать это:-alertDialogBuilder.setCancelable(true);
другое решение этот код был вырезан из исходного кода 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)); }
это решение не имеет этой проблемы :
это отлично работает, за исключением того, что активность внизу также реагирует на событие касания. Есть ли способ предотвратить это? - howettl
этот код используется при использовании нажмите на диалоговое окно, что время hidesoftinput и когда пользователь нажмите внешнюю сторону диалогового окна, что время и softinput и диалоговое окно близки.
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; } };