¿Cómo descartar el diálogo con un clic fuera del diálogo?

Implementé un diálogo personalizado para mi aplicación. Quiero implementar eso cuando el usuario haga clic fuera del diálogo, el diálogo será descartado. ¿Qué tengo que hacer para esto?

Puede usar dialog.setCanceledOnTouchOutside(true); que cerrará el diálogo si toca fuera del diálogo.

Algo como,

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

O si su Diálogo no está en el modelo entonces,

1 – Establezca la bandera – FLAG_NOT_TOUCH_MODAL para el atributo de ventana de su diálogo

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

2 – Agregue otro FLAG_WATCH_OUTSIDE_TOUCH a las propiedades de Windows ,, FLAG_WATCH_OUTSIDE_TOUCH – este es para que el cuadro de diálogo reciba el evento táctil fuera de su región visible.

3 – Anular onTouchEvent() de diálogo y verificar el tipo de acción. si el tipo de acción es ‘ MotionEvent.ACTION_OUTSIDE ‘ significa que el usuario está interactuando fuera de la región de diálogo. Entonces, en este caso, puede atenuar su diálogo o decidir qué desea realizar. ver planos?

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

Para obtener más información, consulte ¿Cómo descartar un diálogo personalizado basado en puntos táctiles? y Cómo descartar su diálogo no modal, cuando se toca fuera de la región de diálogo

Puede usar esta implementación de onTouchEvent. Evita reactjsr debajo de la actividad al evento táctil (como se mencionó anteriormente).

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

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

Simplemente usa

 dialog.setCanceledOnTouchOutside(true); 

O bien, si está personalizando el diálogo utilizando un tema definido en su estilo xml, coloque esta línea en su tema:

 true 
 dialog.setCanceledOnTouchOutside(true); 

para cerrar el diálogo al tocar afuera.

Y si no quiere cerrar al tocar afuera, use el siguiente código:

 dialog.setCanceledOnTouchOutside(false); 

Este método debe evitar por completo las actividades debajo del área gris que recupera los eventos de clic.

Elimine esta línea si la tiene:

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

Pon esto en tu actividad creada

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

luego anula el evento táctil con este

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

Puedes probar esto: –

 AlterDialog alterdialog; alertDialog.setCanceledOnTouchOutside(true); 

o

 alertDialog.setCancelable(true); 

Y si tiene un AlterDialog.Builder entonces puede intentar esto: –

 alertDialogBuilder.setCancelable(true); 

Otra solución de este código fue cortada del código fuente de Android. Simplemente debe agregar estos dos métodos a su código fuente de diálogo.

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

Esta solución no tiene este problema:

Esto funciona muy bien, excepto que la actividad subyacente también reactjs al evento táctil. ¿Hay alguna forma de prevenir esto? – howettl

Este código se usa para cuando se usa, haga clic en el cuadro de diálogo que oculta el tiempo y cuando el usuario hace clic en el lado externo del cuadro de diálogo esa vez que tanto el softinput como el cuadro de diálogo están cerca.

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

Puede hacer que un background ocupe todo el tamaño de pantalla sea transparent y escuchar el evento onClick para dismiss .

Llamar a dialog.setCancelable(false); de tu actividad / fragmento