Як обробити кнопку Назад у діалоговому вікні?


95

Я розробляю програму, яка при натисканні кнопки відкриває діалогове вікно з кнопками ОК та Скасувати.

Це чудово працює.

Коли користувач натискає кнопку "Назад", я обробляю це наступним чином

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

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

Але вищезазначений спосіб не називається. Як я можу з цим впоратися?


1
Ви хочете, щоб користувач міг скасувати діалогове вікно? Або що робить ваша частина onKeyDown?
Крюгер

@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.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});

7
Це, безумовно, найкраща відповідь. Приємно і просто. Не потрібно виявляти KeyEvent. Ідеально.
LargeGlasses

2
Я знаю, що я запізнився, але думав вказати на щось. Це додатково також спрацює, коли користувач клацне десь поза діалоговим вікном. Отже, якщо вам потрібно замінити лише опцію зворотного друку, це не те, що ви шукаєте.
user2520215

5
@ user2520215, якщо ви не хочете, щоб він запускався, коли користувач клацає поза діалоговим вікном, слід встановити dialog.setCanceledOnTouchOutside (false). Це, безумовно, краща відповідь.
Алхассан Абдулкадір

Дякую, що вказали. Тоді це, безумовно, кращий підхід.
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

2

Якщо ви використовуєте 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.