Reputation: 2585
I have an AlertDialog dlgDetails
which is shown from another AlertDialog dlgMenu
. I would like to be able to show dlgMenu again if the user presses the back button in dlgDetails and simply exit the dialog if he presses outside the dialog.
I think the best way to do this is to override onBackPressed
for dlgDetails, but I am not sure how to do that since AlertDialogs must be created indirectly using the Builder.
I am trying to create a derived AlertDialog (public class AlertDialogDetails extends AlertDialog { ...}
) but then I guess I must also extend AlertDialog.Builder
in that class to return an AlertDialogDetails, but isn't there a simpler way? And if not, how would you go about overriding the Builder?
Upvotes: 26
Views: 27554
Reputation:
Here is an actual solution for C#, based on the answer from Pooks:
First, we have to create a new class for handling the event:
private sealed class KeyListener : Java.Lang.Object, IDialogInterfaceOnKeyListener
{
private readonly Action _action;
public KeyListener(Action action)
{
_action = action;
}
public bool OnKey(IDialogInterface dialog, [GeneratedEnum] Android.Views.Keycode keyCode, KeyEvent e)
{
var isBack = keyCode == Android.Views.Keycode.Back
&& e.Action == KeyEventActions.Up
&& !e.IsCanceled;
if (isBack)
_action.Invoke();
return isBack;
}
}
And we need an action to receive the event:
private void OnBackPressed()
{
// ... do the stuff
}
Now, we can set up this event:
var dlgDetails = new AlertDialog.Builder(this)
.SetOnKeyListener(new KeyListener(OnBackPressed))
// add further set ups
.Create();
Upvotes: 0
Reputation: 2585
I finally added a key listener to my dialog to listen to the Back key.
Not as elegant as overriding onBackPressed()
but it works.
Here is the code:
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 ...)
For answer in Kotlin see here:Not working onbackpressed when setcancelable of alertdialog is false
Upvotes: 64
Reputation: 913
I created a new function within the java class and made a call to that function from the onClick method of the dialog 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
}
}
Upvotes: 0
Reputation: 3263
This handles both the BACK button and the click OUTSIDE the dialog:
yourBuilder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.cancel();
// do your stuff...
}
});
dialog.cancel()
is the key: with dialog.dismiss()
this would handle only the click outside of the dialog, as answered above.
Upvotes: 1
Reputation: 300
Found a shorter solution :) try this:
accountDialog = builder.create();
accountDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
activity.finish();
}
});
Upvotes: 7