Comment gérer le bouton Retour avec dans la boîte de dialogue?

95

Je développe une application qui, lorsque le bouton est enfoncé, ouvre une boîte de dialogue avec les boutons OK et Annuler.

Ça fonctionne bien.

Lorsque l'utilisateur appuie sur le bouton de retour, je gère cela comme suit

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

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

Mais la méthode ci-dessus n'est pas appelée. Comment puis-je gérer cela?

Kiran
la source
1
Voulez-vous que l'utilisateur puisse annuler la boîte de dialogue? Ou que fait votre partie onKeyDown?
Krueger
@kiran :: pouvez-vous être un peu plus clair ??
KMI

Réponses:

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
la source
8
il n'est pas nécessaire de rejeter le Dialog; finish()s'occupe déjà de cela. En outre, cette méthode devrait probablement revenir falsepour pouvoir capturer les événements clés ailleurs
slinden77
6
Je pense que la réponse d'Alexc ci-dessous est une meilleure alternative.
Simon Forsberg
23
J'ai ajouté le && event.getAction() == KeyEvent.ACTION_UPà la réponse. Sans cela, le bloc de code sera exécuté deux fois. (Touche BAS et touche HAUT). Dans cet exemple, ce n'est pas si important, mais pour d'autres actions que finish (), cela peut être très important.
Udo Klimaschewski
1
@dmmh si vous n'appelez pas dialog.dismiss()aura une fuite de mémoire.
CONvid19
2
Je suis sûr que vous avez raison, mais dans ce cas, finish()et dialog.dismiss()devrait être inversé dans le code ci-dessus.
slinden77
115

On dirait que vous souhaitez définir OnCancelListener lorsque vous créez la boîte de dialogue. Cela ressemble à ceci:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});
alexc
la source
7
C'est certainement la meilleure réponse. Sympa et simple. Pas besoin de détecter le KeyEvent. Parfait.
LargeGlasses
2
Je sais que je suis trop tard, mais j'ai pensé indiquer quelque chose. Cela sera également déclenché lorsque l'utilisateur clique quelque part en dehors de la boîte de dialogue. Donc, si vous devez uniquement remplacer l'option de presse arrière, ce n'est pas ce que vous recherchez.
user2520215
5
@ user2520215 si vous ne souhaitez pas qu'il se déclenche lorsque l'utilisateur clique en dehors de la boîte de dialogue, vous devez définir dialog.setCanceledOnTouchOutside (false). C'est certainement la meilleure réponse.
Alhassan Abdulkadir
Merci de l'avoir signalé. C'est alors sûrement une meilleure approche.
user2520215
3
Cela ne semble pas fonctionner si une vue personnalisée est utilisée (c'est-à-dire ne pas créer la boîte de dialogue mais simplement hériter de DialogFragment) alors que l'écouteur clé fonctionne dans ce cas.
Julian Honma
19

Vous devez remplacer la OnCancelméthode. Cette méthode appelle la touche Retour. Voici le code qui me convient parfaitement.

 AlertDialog alertDialog;

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

                    dialog.dismiss();                           

            }
}); 

J'espère que cela vous aidera et acceptez-le si cela vous est utile.

Merci..

Ne jamais abandonner
la source
7

Essaye ça

 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
la source
1
Pourquoi ne puis-je pas utiliser setOnCancelListener dans le générateur?
ffleandro
2

Si vous utilisez un DialogFragment, d'après ce que je peux dire, la bonne façon de le faire est de remplacer onCancel ()

J'ai remarqué que setOnCancelListenercela ne fonctionne pas, et setOnKeyListenerfonctionne, mais pour moi, cela a l'effet secondaire amusant qu'il avale toutes les touches si votre boîte de dialogue a un texte d'édition.

Daniel Wilson
la source
1

c'est parce que lorsque votre boîte de dialogue s'ouvre, votre fenêtre navigue vers la boîte de dialogue. Alors maintenant, vous devez gérer keyvotre boîte de dialogue.

Mohammed Azharuddin Shaikh
la source
Bien que correcte, cette réponse n'est pas très informative sur la façon de gérer keydans la boîte de dialogue.
Simon Forsberg
1

Remplacez la méthode onBackPressed()dans votre propre boîte de dialogue et utilisez-la dans votre code:

public class MyDialog extends Dialog {

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

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

Utilisation:

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

Ce code fonctionne:

    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
la source