Jak obsługiwać przycisk Wstecz w oknie dialogowym?

95

Tworzę aplikację, która po naciśnięciu przycisku otwiera okno dialogowe z przyciskami OK i Anuluj.

To działa dobrze.

Kiedy użytkownik naciska przycisk Wstecz, postępuję w następujący sposób

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

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

Ale powyższa metoda nie jest wywoływana. Jak sobie z tym poradzić?

kiran
źródło
1
Czy chcesz, aby użytkownik mógł anulować okno dialogowe? Albo co robi twoja część onKeyDown?
Krueger
@kiran :: czy możesz być trochę bardziej jasny?
KMI

Odpowiedzi:

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
źródło
8
nie ma potrzeby odrzucania Dialog; finish()już się tym zajmuje. Ta metoda prawdopodobnie powinna powrócić, falseaby móc uchwycić kluczowe wydarzenia w innym miejscu
slinden77
6
Myślę, że odpowiedź alexca poniżej jest lepszą alternatywą.
Simon Forsberg,
23
Dodałem && event.getAction() == KeyEvent.ACTION_UPdo odpowiedzi. Bez tego blok kodu zostanie wykonany dwukrotnie. (Klawisz w dół i klawisz w górę). W tym przykładzie nie jest to takie ważne, ale dla innych akcji niż finish () może być bardzo ważne.
Udo Klimaschewski
1
@dmmh, jeśli nie zadzwonisz, dialog.dismiss()spowoduje wyciek pamięci.
CONvid19
2
Jestem pewien, że masz rację, ale w takim przypadku finish()i dialog.dismiss()powinien zostać zamieniony w powyższym kodzie.
slinden77
115

Wygląda na to, że chcesz ustawić OnCancelListener podczas tworzenia okna dialogowego. To wygląda tak:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});
alexc
źródło
7
To zdecydowanie najlepsza odpowiedź. Ładnie i prosto. Nie ma potrzeby wykrywania zdarzenia KeyEvent. Idealny.
LargeGlasses
2
Wiem, że jestem za późno, ale pomyślałem, żeby coś wskazać. To dodatkowo zostanie uruchomione, gdy użytkownik kliknie gdzieś poza oknem dialogowym. Więc jeśli chcesz tylko zastąpić opcję naciśnięcia wstecznego, to nie jest to, czego szukasz.
user2520215
5
@ user2520215, jeśli nie chcesz, aby był on wyzwalany, gdy użytkownik kliknie poza oknem dialogowym, ustaw parametr dialog.setCanceledOnTouchOutside (false). To zdecydowanie lepsza odpowiedź.
Alhassan Abdulkadir
Dzięki za wskazanie. Jest to z pewnością lepsze podejście.
user2520215
3
Wydaje się, że nie działa, jeśli używany jest widok niestandardowy (tj. Nie tworzy okna dialogowego, ale tylko dziedziczy po DialogFragment), podczas gdy nasłuchiwanie kluczy działa w tym przypadku.
Julian Honma,
19

Musisz zastąpić OnCancelmetodę. Ta metoda wymaga naciśnięcia klawisza Wstecz. Oto kod, który dla mnie działa idealnie.

 AlertDialog alertDialog;

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

                    dialog.dismiss();                           

            }
}); 

Mam nadzieję, że to ci pomoże i zaakceptuj je, jeśli okaże się to pomocne.

Dzięki..

Nigdy nie rezygnuj
źródło
7

Spróbuj tego

 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
źródło
1
Dlaczego nie mogę użyć setOnCancelListener w kreatorze?
ffleandro
3

Jeśli używasz DialogFragment, z tego, co mogę powiedzieć, należy to zrobić, aby zastąpić onCancel ()

Zauważyłem, setOnCancelListenerże nie działa i setOnKeyListenerdziała, ale dla mnie ma fajny efekt uboczny, że połyka wszystkie klawisze, jeśli twoje okno dialogowe ma tekst edycji.

Daniel Wilson
źródło
1

Dzieje się tak dlatego, że kiedy otwiera się okno dialogowe, okno przechodzi do okna dialogowego. Więc teraz musisz zająć keysię swoim dialogiem.

Mohammed Azharuddin Shaikh
źródło
Chociaż poprawna, ta odpowiedź nie zawiera zbyt wielu informacji na temat obsługi keyw oknie dialogowym.
Simon Forsberg,
1

Zastąp metodę onBackPressed()w swoim własnym oknie dialogowym i użyj jej w swoim kodzie:

public class MyDialog extends Dialog {

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

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

Posługiwać się:

MyDialog dlg = new MyDialog(context);
dlg.show();
santamoniya
źródło
0

Ten kod działa:

    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
źródło