Android: как переопределить onBackPressed() в AlertDialog?

У меня есть AlertDialog dlgDetails, который отображается из другого AlertDialog dlgMenu. Я хотел бы иметь возможность снова показывать dlgMenu, если пользователь нажимает кнопку «Назад» в dlgDetails, и просто выходить из диалогового окна, если он нажимает за пределами диалогового окна.

Я думаю, что лучший способ сделать это — переопределить onBackPressed для dlgDetails, но я не уверен, как это сделать, поскольку AlertDialogs необходимо создавать косвенно с помощью Builder.

Я пытаюсь создать производный AlertDialog (public class AlertDialogDetails extends AlertDialog { ...}), но тогда я думаю, что должен также расширить AlertDialog.Builder в этом классе, чтобы вернуть AlertDialogDetails, но нет ли более простого способа? А если нет, как бы вы переопределили Builder?


person Pooks    schedule 18.10.2011    source источник
comment
Что ж, я нашел способ сделать это, используя setOnKeyListener() при создании диалога, но мне все же кажется, что лучше всего использовать onBackPressed. Если никто не сможет предложить лучшее решение, чем setOnKeyListener(), то я опубликую свой ответ через несколько часов (сайт все равно не позволит мне опубликовать его сейчас).   -  person Pooks    schedule 18.10.2011
comment
У меня такая же проблема. Но я программировал на Котлине. Если кто-то использует Kotlin, мой вопрос поможет ему/ей: stackoverflow.com/questions/60462748/   -  person MMG    schedule 18.05.2020


Ответы (4)


Наконец-то я добавил в свой диалог прослушиватель клавиш, чтобы слушать клавишу «Назад». Не так элегантно, как переопределение onBackPressed(), но работает. Вот код:

dlgDetails = new AlertDialog.Builder(this)
    .setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey (DialogInterface dialog, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK && 
                event.getAction() == KeyEvent.ACTION_UP && 
                !event.isCanceled()) {
                dialog.cancel();
                showDialog(DIALOG_MENU);
                return true;
            }
            return false;
        }
    })
    //(Rest of the .stuff ...)

Ответ в Kotlin см. здесь: Не работает onbackpressed, когда setcancelable of alertdialog имеет значение false

person Pooks    schedule 19.10.2011
comment
+1 Спасибо за это, это сработало хорошо! Жаль, что метода setOnBackPressed() не существует, поэтому я думаю, что это самый простой способ сделать это. - person Caumons; 09.03.2012
comment
Наконец-то рабочее решение для обработки кнопки «Назад» в моем диалоговом окне. - person Adam Varhegyi; 26.03.2012
comment
работает при нажатии кнопки НАЗАД. Не работает нажатие ВНЕ диалогового окна. - person dentex; 08.10.2013
comment
У меня такая же проблема. Но я программировал на Котлине. Если кто-то использует Kotlin, мой вопрос поможет ему/ей: stackoverflow.com/questions/60462748/ - person MMG; 18.05.2020

Нашел более короткое решение :) попробуйте это:

         accountDialog = builder.create();

        accountDialog.setOnCancelListener(new OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                dialog.dismiss();
                activity.finish();

            }
        });
person Lettings Mall    schedule 27.04.2013
comment
Это довольно хорошее решение, но разве onCancel() не будет вызываться как тогда, когда пользователь нажимает кнопку «Назад», так и когда он щелкает за пределами диалогового окна? Мне нужно различать эти 2 случая. - person Pooks; 30.04.2013
comment
Этот прослушиватель не вызывается при нажатии кнопки «Назад». - person Yoann Hercouet; 06.05.2013
comment
Чтобы обработать как кнопку НАЗАД, так и щелчок ВНЕ диалогового окна: - person dentex; 08.10.2013
comment
Обратите внимание, что setOnCancelListener() доступен для API 17 и выше. - person TheIT; 15.05.2014
comment
У меня такая же проблема. Но я программировал на Котлине. Если кто-то использует Kotlin, мой вопрос поможет ему/ей: stackoverflow.com/questions/60462748/ - person MMG; 18.05.2020

Это обрабатывает как кнопку НАЗАД, так и щелчок ВНЕ диалогового окна:

yourBuilder.setOnCancelListener(new OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        dialog.cancel();
        // do your stuff...
    }
});

dialog.cancel() - это ключ: с dialog.dismiss() это будет обрабатывать только щелчок вне диалогового окна, как указано выше.

person dentex    schedule 08.10.2013
comment
Я использовал OnDismissListener, потому что он также обрабатывает заднюю, внешнюю и отрицательную кнопку. - person Nahuel Barrios; 09.11.2016
comment
У меня такая же проблема. Но я программировал на Котлине. Если кто-то использует Kotlin, мой вопрос поможет ему/ей: stackoverflow.com/questions/60462748/ - person MMG; 18.05.2020

Я создал новую функцию в классе java и вызвал эту функцию из метода onClick диалогового окна Builder.

public class Filename extends Activity(){

@Override
onCreate(){
 //your stuff
 //some button click launches Alertdialog
}

public void myCustomDialog(){
 AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
 //other details for builder
      alertDialogBuilder.setNegativeButton("BACK",
            new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
                         dialod.dismiss;
                         myCustomBack();
                    }
      });

 AlertDialog alertDialog = alertDialogBuilder.create();
 alertDialog.setCanceledOnTouchOutside(true);
 alertDialog.show();
}

public void myCustomBack(){
  if(condition1){
    super.onBackPressed();
  }
  if(condition 2){
    //do  stuff here
  }
}

@Override
public void onBackPressed(){
  //handle case here
  if (condition A)
    //Do this
  else 
    //Do that
}

}
person Deepak Negi    schedule 02.06.2014
comment
Спасибо за предложение. Однако идея состоит не в том, чтобы создать отрицательную кнопку, вызываемую назад, а в том, чтобы иметь специальную обработку клавиши возврата телефона при отображении диалогового окна. Обработка onBackPressed активности не помогает, потому что мы не знаем, отображается диалоговое окно или нет, без добавления флага, что немного запутанно. - person Pooks; 03.06.2014
comment
У меня такая же проблема. Но я программировал на Котлине. Если кто-то использует Kotlin, мой вопрос поможет ему/ей: stackoverflow.com/questions/60462748/ - person MMG; 18.05.2020