Evitar que el diálogo de actividad de Android se cierre al tocar el exterior

229

Tengo una actividad que usa el estilo Theme.Dialog de modo que es una ventana flotante sobre otra actividad. Sin embargo, cuando hago clic fuera de la ventana de diálogo (en la actividad de fondo), el diálogo se cierra. ¿Cómo puedo detener este comportamiento?

Fergusmac
fuente
1
¿Por qué harías eso por cierto? SI el comportamiento que desea es de un diálogo, ¿por qué no utilizar un diálogo? En cuanto a su pregunta, no creo que haya una solución para eso.
Kumar Bibek
Los diálogos de @KumarBibek son limitados cuando se trata de personalizaciones de diseño ... por eso es una actividad. Incluso los documentos del desarrollador recomiendan este enfoque para una personalización flexible
Leo
1
Y lo que quiere el OP es un diálogo modal , es decir, un diálogo que obligue al usuario a responder, como OK o Sí / No. El usuario no debería poder simplemente hacer clic fuera.
Scott Biggs

Respuestas:

34

Esto te puede ayudar. Es una forma de manejar el evento de toque externo:

¿Cómo cancelar un cuadro de diálogo temático como Actividad cuando se toca fuera de la ventana?

Al captar el evento y no hacer nada, creo que puedes evitar el cierre. Pero lo que es extraño, sin embargo, es que el comportamiento predeterminado de su diálogo de actividad no debe cerrarse cuando toca afuera.

(PD: el código usa WindowManager.LayoutParams)

Michel-F. Portzert
fuente
1
Sin embargo, el objeto no es un diálogo, es una Actividad que usa el estilo de diálogo. La actividad no tiene este método, y no se puede enviar a Diálogo.
Fergusmac
Su publicación es exactamente lo contrario de lo que se le preguntó. preguntó cómo evitar el cierre, no cómo provocarlo.
ChuckKelly
44
Que es lo que explicó con "Al captar el evento y no hacer nada, creo que puedes evitar el cierre".
Metter
44
por alguna razón, después de hacer todo el FLAG_NOT_MODAL, WATCH_OUTSIDE_TOUCH, el toque externo no cierra las actividades, pero se hace clic en el botón detrás de la actividad. alguna idea para eso?
njzk2
Tenga en cuenta que los cuadros de diálogo tienen una sombra (al menos hasta ahora (8.0)): si hace clic en la sombra, Android interpretará ese clic tal como estaba dentro del cuadro de diálogo. Solo quería compartir esto con el mundo, me tomó 10 minutos obtenerlo.
Lorenzo Von Matterhorn
459

Para evitar que el cuadro de diálogo se descarte al presionar la tecla Atrás, use esto

dialog.setCancelable(false);

Y para evitar que el cuadro de diálogo se descarte en el toque externo, use esto

 dialog.setCanceledOnTouchOutside(false);
Singhak
fuente
44
Esta respuesta es útil, pero esta pregunta es sobre la actividad que utiliza el atributo Theme.Dialog.
Paresh Mayani
15
Sé cuando me doy cuenta de que es demasiado tarde ya que ayuda a muchas personas, por lo que no lo eliminé.
Singhak
12
Sé que esto realmente no se refería a la pregunta, pero esto me ayudó. ¡Gracias!
dennisdrew
55
Esta es la mejor respuesta. Sospecho que la mayoría de las personas que encuentran esta pregunta están buscando una manera de evitar que el estándar se AlertDialogcierre al tacto, y eso es lo que proporciona esta respuesta.
Aroth
20
En las versiones más nuevas de AlertDialog, solo necesita usarsetCancelable(false)
Kobi Tate
120

Lo que realmente tiene es una Actividad (incluso si parece un Diálogo), por lo tanto, debe llamar setFinishOnTouchOutside(false)desde su actividad si desea mantenerla abierta cuando se hace clic en la actividad en segundo plano.

EDITAR: esto solo funciona con Android API nivel 11 o superior

artex
fuente
44
Esto no le impide presionar el botón "atrás" en su actividad. Así que también debes anular onBackPressed()no hacer nada en su cuerpo
Alex Bonel
No está impidiendo el botón "atrás" en esa actividad de diálogo sin onBackPressed (). Funciona perfecto con this.setFinishOnTouchOutside (falso).
Kunalxigxag
68

Lo que funcionó para mí fue crear DialogFragmentun conjunto para que no sea cancelable:

dialog.setCancelable(false);
Petr
fuente
1
No es útil. Esta pregunta es sobre actividades, no diálogos.
Scott Biggs
20

Cuando use el diálogo como una actividad en onCreate, agregue esto

setFinishOnTouchOutside(false);
Ronny Shibley
fuente
17

Para API 10 superior, el cuadro de diálogo desaparece cuando se toca al aire libre, mientras que en un nivel inferior a API 11, el cuadro de diálogo no desaparece. Para evitar esto, debe hacer:

En styles.xml:<item name="android:windowCloseOnTouchOutside">false</item>

O

En el onCreate()método, use:this.setFinishOnTouchOutside(false);

Nota: para API 10 y versiones inferiores, este método no tiene efecto y no es necesario.

ilw
fuente
14

Establecer el diálogo cancelable como falso es suficiente, y si toca fuera del diálogo de alerta o hace clic en el botón Atrás, desaparecerá el diálogo de alerta. Entonces usa este:

setCancelable(false)

Y la otra función ya no es necesaria: dialog.setCanceledOnTouchOutside(false);

Si está creando un diálogo temporal y se pregunta dónde colocar esta línea de código, aquí hay un ejemplo:

new AlertDialog.Builder(this)
                        .setTitle("Trial Version")
                        .setCancelable(false)
                        .setMessage("You are using trial version!")
                        .setIcon(R.drawable.time_left)
                        .setPositiveButton(android.R.string.yes, null).show();
BillOverFlow
fuente
12

Use este código, me está funcionando

 AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
 alertDialog.setCancelable(false);

Aslam Patel
fuente
¡Esta debería ser la respuesta correcta, si pudiera hacer la pregunta correcta!
alijunior
2
¡Esta sería la respuesta correcta si el OP preguntara por los diálogos ! Pero la pregunta es sobre Actividades, un caso bastante diferente.
Scott Biggs
11
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true); 
//use this to dismiss the dialog on outside click of dialog

dialog.setCanceledOnTouchOutside(false);
//use this for not to dismiss the dialog on outside click of dialog.

Mire este enlace para más detalles sobre el diálogo.

dialog.setCancelable(false);
//used to prevent the dismiss of dialog on backpress of that activity

dialog.setCancelable(true);
//used to dismiss the dialog on onbackpressed of that activity
anand krish
fuente
Tenga en cuenta que la pregunta se refiere a Actividades utilizadas como diálogos, NO a la clase Diálogo.
Scott Biggs
8

Simplemente,

alertDialog.setCancelable(false);

evitar que el usuario haga clic fuera del cuadro de diálogo.


fuente
7

El cuadro de diálogo de alerta está en desuso, así que use el cuadro de diálogo Diálogo = nuevo cuadro de diálogo (esto);

Para evitar el cierre en contacto externo

dialog.setCanceledOnTouchOutside(false);
Muhammed Fasil
fuente
5

¡Úselo setFinishOnTouchOutside(false)para API> 11 y no se preocupe porque el comportamiento predeterminado de Android de que el diálogo temático de actividad no se terminará en el toque externo para API <11 :) !!

Vishal Pandey
fuente
5

Lo uso en onCreate (), parece funcionar en cualquier versión de Android; probado en 5.0 y 4.4.x, no se puede probar en Gingerbread, los dispositivos Samsung (Nota 1 con GB) lo tienen de esta manera por defecto:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    {
        setFinishOnTouchOutside(false);
    }
    else
    {
        getWindow().clearFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
    }

    super.onCreate(savedInstanceState);
3c71
fuente
4
        alert.setCancelable(false);
        alert.setCanceledOnTouchOutside(false);

Supongo que esto te ayudará. Funcionó para mí

usuario2532065
fuente
1
Intenta explicar también por qué esto funcionará ... Solo un volcado de código no es una buena respuesta.
Codebender
3

Aquí está mi solución:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select The Difficulty Level");
builder.setCancelable(false);
Akhter Al Amin
fuente
2

También es posible asignar diferentes acciones implementando onCancelListener:

alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){                   
    @Override
    public void onCancel(DialogInterface dialogInterface) {
        //Your custom logic
    } 
});
Adae Rodríguez
fuente
¿Cómo puedo identificar si se llama a cancelar por tocar fuera del diálogo de alerta?
cegprakash
¡Muy útil para crear acciones personalizadas al tocar fuera de un cuadro de diálogo de alerta!
Adam S.
1

Estaba enfrentando el mismo problema. Para manejarlo configuré un OntouchListenercuadro de diálogo y no hago nada dentro. Pero el diálogo se descarta al girar la pantalla también. Para solucionarlo, configuré una variable para decirme si el diálogo normalmente se ha descartado. Luego configuro OnDismissListenera mi diálogo y en el interior verifico la variable. Si el cuadro de diálogo tiene descuido, normalmente no hago nada, o de lo contrario vuelvo a ejecutar el cuadro de diálogo (y establezco su estado como cuando lo descarto en mi caso).

Madara
fuente
1

builder.setCancelable (falso);


mensaje público vacío (Ver v) {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("¿Quieres ir a el Menú principal?");
    builder.setMessage("Al presionar SI iras a el menú y saldras de la materia.");
    builder.setPositiveButton("SI", null);
    builder.setNegativeButton("NO", null);
    builder.setCancelable(false);
    builder.show();
}
Alex Skriivordemgentschenfelde
fuente
1
Hola Alex. Bienvenido a StackOverflow y gracias por tu respuesta. ¿Podría editar su respuesta para describir qué hace su código y cómo esto resuelve el problema del OP? Se desaconsejan las respuestas de solo código, ya que no enseñan ni explican por qué . ¡Gracias!
Tim Malone
-1

Esta es la respuesta perfecta a todas tus preguntas ... Espero que disfrutes codificando en Android

new AlertDialog.Builder(this)
            .setTitle("Akshat Rastogi Is Great")
            .setCancelable(false)
            .setMessage("I am the best Android Programmer")
            .setPositiveButton("I agree", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();

                }
            })
            .create().show();
Akshat Rasogi
fuente
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría enormemente su valor a largo plazo al mostrar por qué esta es una buena solución al problema y la haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.
Maximilian Peters