Wie gehe ich mit der Schaltfläche Zurück im Dialogfeld um?


94

Ich entwickle eine Anwendung, die beim Drücken der Schaltfläche einen Dialog mit den Schaltflächen OK und Abbrechen öffnet.

Es funktioniert gut.

Wenn der Benutzer die Zurück-Taste drückt, gehe ich wie folgt vor

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

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

Die obige Methode wird jedoch nicht aufgerufen. Wie kann ich damit umgehen?


1
Möchten Sie, dass der Benutzer den Dialog abbrechen kann? Oder was macht Ihr onKeyDown-Teil?
Krüger

@ kiran :: kannst du etwas klarer sein?
KMI

Antworten:


237
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
es besteht keine Notwendigkeit, das zu entlassen Dialog; finish()kümmert sich schon darum. Außerdem sollte diese Methode wahrscheinlich zurückkehren false, um wichtige Ereignisse an anderer Stelle erfassen zu können
slinden77

6
Ich denke, die Antwort von alexc unten ist eine bessere Alternative.
Simon Forsberg

23
Ich habe das && event.getAction() == KeyEvent.ACTION_UPder Antwort hinzugefügt . Ohne sie wird der Codeblock zweimal ausgeführt. (Taste AB und Taste AUF). In diesem Beispiel ist es nicht so wichtig, aber für andere Aktionen als finish () kann es sehr wichtig sein.
Udo Klimaschewski

1
@dmmh Wenn Sie nicht anrufen, dialog.dismiss()wird ein Speicherverlust auftreten.
CONvid19

2
Ich bin sicher, Sie haben Recht, aber in diesem Fall finish()und dialog.dismiss()sollte im obigen Code umgeschaltet werden.
Slinden77

115

Klingt so, als ob Sie den OnCancelListener beim Erstellen des Dialogfelds festlegen möchten. Es sieht aus wie das:

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

7
Dies ist definitiv die beste Antwort. Schön und einfach. Das KeyEvent muss nicht erkannt werden. Perfekt.
LargeGlasses

2
Ich weiß, dass ich zu spät bin, dachte aber daran, auf etwas hinzuweisen. Dies wird zusätzlich auch ausgelöst, wenn der Benutzer irgendwo außerhalb des Dialogfelds klickt. Wenn Sie also nur die Option zum Zurückdrücken überschreiben müssen, ist dies nicht das, wonach Sie suchen.
user2520215

5
@ user2520215 Wenn Sie nicht möchten, dass es ausgelöst wird, wenn der Benutzer außerhalb des Dialogfelds klickt, sollten Sie dialog.setCanceledOnTouchOutside (false) festlegen. Dies ist definitiv die bessere Antwort.
Alhassan Abdulkadir

Vielen Dank für den Hinweis. Dies ist dann sicherlich ein besserer Ansatz.
user2520215

3
Dies scheint nicht zu funktionieren, wenn eine benutzerdefinierte Ansicht verwendet wird (dh nicht das Dialogfeld erstellt, sondern nur von DialogFragment übernommen wird), während der Key Listener in diesem Fall funktioniert.
Julian Honma

19

Sie müssen die OnCancelMethode überschreiben . Diese Methode ruft beim Drücken der Zurück-Taste auf. Hier ist Code, der perfekt für mich funktioniert.

 AlertDialog alertDialog;

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

                    dialog.dismiss();                           

            }
}); 

Hoffe, dies wird dir helfen und akzeptiere es, wenn es dir hilfreich ist.

Vielen Dank..


7

Versuche dies

 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
Warum kann ich setOnCancelListener im Builder nicht verwenden?
ffleandro


1

Dies liegt daran, dass Ihr Fenster beim Öffnen Ihres Dialogfelds auf Dialog ausgerichtet ist. Jetzt müssen Sie sich also um keyIhren Dialog kümmern.


Obwohl richtig, ist diese Antwort nicht sehr informativ über den Umgang keyim Dialog.
Simon Forsberg

1

Überschreiben Sie die Methode onBackPressed()in Ihrem eigenen Dialogfeld und verwenden Sie sie in Ihrem Code:

public class MyDialog extends Dialog {

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

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

Verwenden:

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

0

Dieser Code funktioniert:

    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();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.