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?

kiran
quelle
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;
            }
        });
Yasin Hassanien
quelle
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
    }
});
alexc
quelle
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..

Niemals aufhören
quelle
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;


                        }
                    })
NitZRobotKoder
quelle
1
Warum kann ich setOnCancelListener im Builder nicht verwenden?
ffleandro
2

Wenn Sie ein DialogFragment verwenden, kann ich sagen, dass der richtige Weg darin besteht, onCancel () zu überschreiben.

Mir ist aufgefallen, dass setOnCancelListeneres nicht funktioniert und setOnKeyListenerfunktioniert, aber für mich hat es den lustigen Nebeneffekt, dass es alle Tasten verschluckt, wenn Ihr Dialog einen Bearbeitungstext enthält.

Daniel Wilson
quelle
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.

Mohammed Azharuddin Shaikh
quelle
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();
Santamoniya
quelle
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();
Andrew Glukhoff
quelle