Come gestire il pulsante Indietro nella finestra di dialogo?


95

Sto sviluppando un'applicazione che quando si preme il pulsante, apre una finestra di dialogo con i pulsanti OK e Annulla.

Funziona bene.

Quando l'utente preme il pulsante Indietro, lo gestisco come segue

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

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

Ma il metodo sopra non viene chiamato. Come posso gestirlo?


1
Vuoi che l'utente possa annullare la finestra di dialogo? O cosa fa la tua parte onKeyDown?
Krueger

@kiran :: puoi essere un po 'più chiaro ??
KMI

Risposte:


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
non è necessario chiudere il Dialog; finish()si occupa già di questo. Inoltre, questo metodo probabilmente dovrebbe tornare falseper essere in grado di catturare eventi chiave altrove
slinden77

6
Penso che la risposta di alexc di seguito sia un'alternativa migliore.
Simon Forsberg

23
Ho aggiunto il && event.getAction() == KeyEvent.ACTION_UPalla risposta. Senza di esso, il blocco di codice verrà eseguito due volte. (Tasto GIÙ e tasto SU). In questo esempio non è così importante, ma per altre azioni oltre a finish (), potrebbe essere molto importante.
Udo Klimaschewski

1
@dmmh se non chiami dialog.dismiss()otterrà una perdita di memoria.
CONvid19

2
Sono sicuro che hai ragione, ma in quel caso finish()e dialog.dismiss()deve essere acceso in giro per il codice di cui sopra.
slinden77

115

Sembra che tu voglia impostare OnCancelListener quando crei la finestra di dialogo. Assomiglia a questo:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});

7
Questa è sicuramente la migliore risposta. Bello e semplice. Non è necessario rilevare KeyEvent. Perfetto.
LargeGlasses

2
So di essere in ritardo, ma ho pensato di indicare qualcosa. Questo inoltre verrà attivato anche quando l'utente fa clic da qualche parte al di fuori della finestra di dialogo. Quindi, se hai bisogno di ignorare solo l'opzione di back press, questo non è quello che stai cercando.
user2520215

5
@ user2520215 se non si desidera che si attivi quando l'utente fa clic al di fuori della finestra di dialogo, è necessario impostare dialog.setCanceledOnTouchOutside (false). Questa è sicuramente la risposta migliore.
Alhassan Abdulkadir

Grazie per avermelo fatto notare. Questo è quindi sicuramente un approccio migliore.
user2520215

3
Questo non sembra funzionare se viene utilizzata una vista personalizzata (cioè non creando la finestra di dialogo ma solo ereditando da DialogFragment) mentre il listener chiave funziona in quel caso.
Julian Honma

19

Devi sovrascrivere il OnCancelmetodo. Questo metodo richiede la pressione del tasto Indietro. Ecco il codice che funziona perfettamente per me.

 AlertDialog alertDialog;

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

                    dialog.dismiss();                           

            }
}); 

Spero che questo ti aiuti e accettalo se ti è utile.

Grazie..


7

Prova questo

 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
Perché non posso usare setOnCancelListener nel Builder?
ffleandro


1

è perché quando il tuo dialogo si apre, la tua finestra naviga focalizzata su Dialog. Quindi ora devi gestire keyil tuo dialogo.


Sebbene corretta, questa risposta non è molto istruttiva su come gestirla keynella finestra di dialogo.
Simon Forsberg

1

Sostituisci il metodo onBackPressed()nella tua finestra di dialogo e usalo nel tuo codice:

public class MyDialog extends Dialog {

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

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

Uso:

MyDialog dlg = new MyDialog(context);
dlg.show();

0

Questo codice funziona:

    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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.