Как работать с кнопкой Назад в диалоге?

95

Я разрабатываю приложение, которое при нажатии кнопки открывает диалоговое окно с кнопками ОК и Отмена.

Работает нормально.

Когда пользователь нажимает кнопку "Назад", я обрабатываю это следующим образом

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

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

Но вышеуказанный способ не вызывается. Как мне с этим справиться?

Киран
источник
1
Вы хотите, чтобы пользователь мог отменить диалог? Или что делает ваша часть onKeyDown?
Krueger
@kiran :: можешь быть немного понятнее ??
KMI

Ответы:

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
нет необходимости сбрасывать со счетов Dialog; finish()уже позаботится об этом. Кроме того, этот метод, вероятно, должен вернуться, falseчтобы иметь возможность захватывать ключевые события в другом месте
slinden77
6
Я думаю, что ответ alexc ниже - лучшая альтернатива.
Саймон Форсберг,
23
Я добавил && event.getAction() == KeyEvent.ACTION_UPк ответу. Без него блок кода будет выполнен дважды. (Клавиша ВНИЗ и клавиша ВВЕРХ). В этом примере это не так важно, но для других действий, кроме finish (), это может быть очень важно.
Удо Климащевски
1
@dmmh, если вы не позвоните, dialog.dismiss()произойдет утечка памяти.
CONvid19
2
Я уверен, что вы правы, но в этом случае finish()и dialog.dismiss()следует поменять местами в приведенном выше коде.
slinden77
115

Похоже, вы хотите установить OnCancelListener при создании Dialog. Выглядит это так:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});
Alexc
источник
7
Это определенно лучший ответ. Красиво и просто. Нет необходимости обнаруживать KeyEvent. Отлично.
LargeGlasses
2
Я знаю, что опоздал, но подумал, что нужно указать на что-то. Это также будет срабатывать, когда пользователь щелкает где-то вне диалогового окна. Так что, если вам нужно только переопределить опцию обратного нажатия, это не то, что вы ищете.
user2520215 05
5
@ user2520215, если вы не хотите, чтобы он запускался, когда пользователь щелкает вне диалогового окна, вы должны установить dialog.setCanceledOnTouchOutside (false). Это определенно лучший ответ.
Alhassan Abdulkadir
Спасибо, что указали. Тогда это, безусловно, лучший подход.
user2520215 02
3
Похоже, это не работает, если используется настраиваемое представление (т.е. не создается диалоговое окно, а просто наследуется от DialogFragment), в то время как в этом случае работает прослушиватель ключа.
Джулиан Хонма,
19

Вам нужно переопределить OnCancelметод. Этот метод вызывает нажатие клавиши «Назад». Вот код, который мне идеально подходит.

 AlertDialog alertDialog;

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

                    dialog.dismiss();                           

            }
}); 

Надеюсь, это поможет вам, и примите это, если это будет полезно для вас.

Спасибо..

Никогда не выйти
источник
7

Попробуй это

 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
источник
1
Почему я не могу использовать setOnCancelListener в Builder?
ffleandro 06
3

Если вы используете DialogFragment, из того, что я могу сказать, правильный способ сделать это - переопределить onCancel ()

Я заметил, setOnCancelListenerчто не работает, и setOnKeyListenerработает, но для меня есть забавный побочный эффект: он проглатывает все клавиши, если в вашем диалоге есть текст редактирования.

Дэниел Уилсон
источник
1

это потому, что, когда ваш диалог открывается, ваше окно переходит к диалогу. Итак, теперь вам нужно заняться keyсвоим диалогом.

Мохаммед Ажаруддин Шейх
источник
Несмотря на то, что этот ответ правильный, он не очень информативен о том, как работать keyв диалоговом окне.
Саймон Форсберг,
1

Переопределите метод onBackPressed()в вашем собственном диалоге и используйте его в своем коде:

public class MyDialog extends Dialog {

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

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

Использование:

MyDialog dlg = new MyDialog(context);
dlg.show();
Сантамония
источник
0

Этот код работает:

    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();
Андрей Глухофф
источник