Запретить кнопку "Назад" от закрытия диалогового окна

Я пытаюсь предотвратить закрытие окна AlertDialog при нажатии кнопки "Назад" в Android. Я придерживался обоих популярных методов в этом потоке, а с помощью System.out.println я вижу, что в обоих случаях код выполняется. Тем не менее, кнопка "Назад" все еще закрывает диалоговое окно.

Что я могу делать неправильно? В конечном счете, я пытаюсь предотвратить закрытие диалогового окна кнопки "Назад" - это выражение об отказе, которое отображается при первом запуске приложения, и я не хочу, чтобы у пользователя был какой-либо параметр, но нажмите кнопку "Принять" в чтобы приложение продолжалось.

Ответ 1

Просто используйте setCancelable():

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);

Это предотвращает закрытие диалогового окна кнопки "Назад", но оставляет "отрицательную" кнопку неповрежденной, если вы решили использовать ее.


В то время как любой пользователь, который не хочет принимать ваши условия обслуживания, может нажать кнопку "домой", в свете комментария Squonk, еще два способа предотвратить "отказ от" пользовательского соглашения. Одна из них - простая кнопка "Отказаться", а другая переопределяет кнопку "Назад" в диалоговом окне:

builder.setNegativeButton("Refuse", new OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
               finish();
           }
       })
       .setOnKeyListener(new OnKeyListener() {
           @Override
           public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
               if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)
                   finish();
               return false;
           }
       });

Ответ 2

Чтобы кнопка "Назад" не закрывала диалоговое окно (без зависимости от Activity), просто следующий код:

alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        // Prevent dialog close on back press button
        return keyCode == KeyEvent.KEYCODE_BACK;
    }
});

Ответ 3

Используйте setCancelable(false)

SampleDialog sampleDialog = SampleDialog.newInstance();
sampleDialog.setCancelable(false);
sampleDialog.show(getSupportFragmentManager(), SampleDialog.class.getSimpleName());

Ответ 4

Только это сработало для меня:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(title);
builder.setMessage(content);

/**
 * Make it when the Back button is pressed, the dialog isn't dismissed.
 */
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            Utilities.makeToast(getContext(), "There is no way back!");
            return true; // Consumed
        }
        else {
            return false; // Not consumed
        }
    }
});

Dialog dialog = builder.create();

/**
 * Make it so touching on the background activity doesn't close the dialog
 */
dialog.setCanceledOnTouchOutside(false);

return dialog;

Как вы можете видеть, я также добавил строку dialog.setCanceledOnTouchOutside(false);, поэтому нажатие вне диалогового окна не приводит к ее закрытию.

Ответ 5

При использовании DialogFragment вам нужно будет вызвать setCancelable() на фрагменте, а не в диалоговом окне:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    dialog = new ProgressDialog(getActivity());
    dialog.setIndeterminate(true);
    dialog.setMessage(...);
    setCancelable(false);

    return dialog;
}

Вызов dialog.setCancelable() кажется неэффективным. Похоже, что DialogFragment не обращает внимания на настройку диалога для отмены.