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


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
    }
});

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;


                        }
                    })

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();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.