¿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?


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

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

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..


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;


                        }
                    })

1
¿Por qué no puedo usar setOnCancelListener en Builder?
ffleandro


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.


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

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();
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.