¿Cómo manejar el botón Atrás en el diálogo?

95

Estoy desarrollando una aplicación que cuando se presiona el botón, abre un diálogo con los botones Aceptar y Cancelar.

Funciona bien.

Cuando el usuario presiona el botón Atrás, estoy manejando esto de la siguiente manera

public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if ((keyCode == KeyEvent.KEYCODE_BACK)) 
    {

    }
 return super.onKeyDown(keyCode, event);
}

Pero el método anterior no se llama. ¿Cómo puedo manejar esto?

Kiran
fuente
1
¿Quiere que el usuario pueda cancelar el diálogo? ¿O qué hace tu parte de onKeyDown?
Krueger
@kiran :: ¿puedes ser un poco más claro ??
KMI

Respuestas:

238
dialog.setOnKeyListener(new Dialog.OnKeyListener() {

            @Override
            public boolean onKey(DialogInterface arg0, int keyCode,
                    KeyEvent event) {
                // TODO Auto-generated method stub
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    finish();
                    dialog.dismiss();
                }
                return true;
            }
        });
Yasin Hassanien
fuente
8
no hay necesidad de descartar Dialog; finish()ya se encarga de esto. Además, este método probablemente debería volver falsea poder capturar eventos clave en otros lugares
slinden77
6
Creo que la respuesta de alexc a continuación es una mejor alternativa.
Simon Forsberg
23
Agregué el && event.getAction() == KeyEvent.ACTION_UPa la respuesta. Sin él, el bloque de código se ejecutará dos veces. (Tecla ABAJO y tecla ARRIBA). En este ejemplo no es tan importante, pero para otras acciones además de terminar (), podría ser muy importante.
Udo Klimaschewski
1
@dmmh, si no llamas, se dialog.dismiss()producirá una pérdida de memoria.
CONvid19
2
Estoy seguro de que tienes razón, pero en ese caso finish()y dialog.dismiss()se debe cambiar todo en el código de seguridad.
slinden77
115

Parece que desea configurar OnCancelListener cuando crea el cuadro de diálogo. Se parece a esto:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});
alexc
fuente
7
Esta es definitivamente la mejor respuesta. Agradable y sencillo. No es necesario detectar el KeyEvent. Perfecto.
LargeGlasses
2
Sé que llegué demasiado tarde, pero pensé en señalar algo. Además, esto también se activará cuando el usuario haga clic en algún lugar fuera del cuadro de diálogo. Entonces, si solo necesita anular la opción de retroceso, entonces esto no es lo que está buscando.
user2520215
5
@ user2520215 si no desea que se active cuando el usuario hace clic fuera del cuadro de diálogo, debe establecer dialog.setCanceledOnTouchOutside (false). Esta es definitivamente la mejor respuesta.
Alhassan Abdulkadir
Gracias por señalar. Este es seguramente un enfoque mejor.
user2520215
3
Esto no parece funcionar si se usa una vista personalizada (es decir, no se crea el cuadro de diálogo sino que se hereda de DialogFragment) mientras que el oyente de claves funciona en ese caso.
Julian Honma
19

Necesita anular el OnCancelmétodo. Este método requiere que se presione la tecla Atrás. Aquí está el código que funciona perfecto para mí.

 AlertDialog alertDialog;

    alertDialog.setOnCancelListener(new OnCancelListener() 
    {                   
           @Override
            public void onCancel(DialogInterface dialog) 
             {
               // TODO Auto-generated method stub

                    dialog.dismiss();                           

            }
}); 

Espero que esto le ayude y acéptelo si le resulta útil.

Gracias..

Nunca renunciar
fuente
7

Prueba esto

 new AlertDialog.Builder(this).setOnKeyListener(new DialogInterface.OnKeyListener() {

                        @Override
                        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {

                            if(keyCode == KeyEvent.KEYCODE_BACK){
                                Logger.d(TAG, "--------- Do Something -----------");
                                return true;
                            }
                            return false;


                        }
                    })
NitZRobotKoder
fuente
1
¿Por qué no puedo usar setOnCancelListener en Builder?
ffleandro
2

Si está utilizando un DialogFragment, por lo que puedo decir, la forma correcta de hacerlo es anular onCancel ()

Noté setOnCancelListenerque no funciona, y setOnKeyListenerfunciona, pero para mí tiene el divertido efecto secundario de que se traga todas las teclas si su diálogo tiene un texto de edición.

Daniel Wilson
fuente
1

se debe a que cuando se abre su cuadro de diálogo, su ventana navega hacia el cuadro de diálogo. Entonces ahora tienes que manejar keytu Diálogo.

Mohammed Azharuddin Shaikh
fuente
Aunque es correcta, esta respuesta no es muy informativa sobre cómo manejar keyen el diálogo.
Simon Forsberg
1

Anule el método onBackPressed()en su propio cuadro de diálogo y utilícelo en su código:

public class MyDialog extends Dialog {

    public MyDialog(@NonNull Context context) {
        super(context);
    }

    @Override
    public void onBackPressed() {
        // Do what you want
    }
}

Utilizar:

MyDialog dlg = new MyDialog(context);
dlg.show();
santamoniya
fuente
0

Este código funciona:

    Dialog dlg = new Dialog(thisAct, R.style.DialogTheme);
    dlg.setContentView(view);
    dlg.setCancelable(false);
    dlg.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
    dlg.setOnKeyListener((arg0, keyCode, event) -> {
        Timber.d("onKey(%d)", keyCode);
        //{home intercepting
        if ((keyCode == KeyEvent.KEYCODE_HOME)) {
            Timber.i("HOME pressed");
            return true;
        }

        return true;
    });
    dlg.show();
Andrew Glukhoff
fuente