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


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

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

6   51  

6 ответов:

просто использовать setCancelable() характеристика:

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

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


В то время как любой пользователь, который не хочет принимать ваши условия обслуживания, может нажать кнопку home, в свете комментария 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;
           }
       });

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

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

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

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

    return dialog;
}

вызов dialog.setCancelable() кажется, не имеют никакого эффекта. Кажется, что DialogFragment не принимает во внимание настройки диалогового окна для отмены.

использовать setCancelable(false)

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

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

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); строка, поэтому нажатие за пределами диалогового окна не приводит к его закрытию.

в jQuery Mobile всплывающее окно добавляет хэш к url-адресу, следующий код позволяет обратно закрыть всплывающее окно при открытии и вернуться в приложение при закрытии. Вы можете использовать ту же логику для пользовательского интерфейса.

@Override
public void onBackPressed() {

    // check if modal is open #&ui-state=dialog

    if (webView.getVisibility() == View.VISIBLE && webView.getUrl().contains("#&ui-state=dialog")) {
        // don't pass back button action
        if (webView.canGoBack()) {
            webView.goBack();
        }
    } else {
        // pass back button action
        super.onBackPressed();
    }
}