tags:

views:

974

answers:

6

Hey!

Coming from the .NET-environment Im am now looking to understand how Dialogs work in Android.

In .NET, when calling MessageBox.Show(...) that creates and shows a popup dialog. In the call to Show I can specify what buttons should be available in the popup, for example:

DialogResult myDialogResult = MessageBox.Show("My text here", "My caption here", MessageBoxButtons.YesNoCancel);

As you can see, the call to Show returns a DialogResult when a button is pressed in the popup, informing me what button was clicked. Note that in .NET, execution is halted at the line where the call to Show(...) is made, so it can return the value when a button is pressed.

If I in the above example press "No" the myDialogResult will be equal to

myDialogResult == DialogResult.No

Since I find the .NET-way of using/creating popups very easy and intuitive, I would like that way of creating popups in Android too.

So, the question is if anyone know how to "halt execution" like with the MessageBox.Show, and then return a value whenever the Button is pressed (and the dialog goes away)?

Regards


EDIT 1: To be a little bit more clear:

I need for the execution to halt and wait until the user has chosen a button to click in the popup. The code that follow the call to show the Dialog is dependent on what button is clicked in the Dialog.

Thats why I cannot use what Erich and Alex suggest, since writing code in the onClick-methods as suggested below is not gonna work. The reason is that I cannot continue the "normal execution". Let me take an example:

Let me take an example:

int nextStep = 0; // this variable will not be reached from within the onClick-methods

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Hello!")
       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                nextStep = 1; // *** COMPILER ERROR!! ***
            }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                nextStep = 2; // *** COMPILER ERROR!! ***
            }
        })
        .create().show();

if (nextStep == 1)
{
    // then do some damage
}
else if (nextStep == 2
    // dont do damage

If I wanted the execution to be dependent on the choice in the popup, I would somehow have to make all the variables in the "normal execution" (in this case nextStep) available in the onClick-methods, and that sounds like hell to me.

EDIT 2:

Another obvious example would be a popup asking "Do you want to continue" with the options "Yes" and "No".

If the user presses "Yes", the whole method should be aborted otherwise it should continue execution. How do you solve that nicely?

Regards

A: 

you set onclick listeners to you buttons. dissmis dialog and do your action. Don't need to halt anything

protected Dialog onCreateDialog(int id) {
  return new AlertDialog.Builder(this).setTitle(R.string.no_connection).setIcon(android.R.drawable.ic_dialog_alert).setView(textEntryView).setPositiveButton(R.string.exit, new DialogInterface.OnClickListener() 
{

   public void onClick(DialogInterface dialog, int whichButton) {

  // Here goes what you want to do
  }

})
}

to call - ex - showDialog(DIALOG_ERROR_PREF);

More http://developer.android.com/guide/topics/ui/dialogs.html

Alex Volovoy
Hey, that was not really what I wanted I think. Whenever a popup is display, the code that follows should NOT be executed until after I have pressed one of the buttons in the popup. The value of the button-press should be returned to the caller, so that the caller then can decide what to do... I will update my question above.
Ted
Since it's not really a .Net i think you have to adapt. And it's not a desktop either. Break your flow into events. You've did some action to display dialog. Now User reacts by pressing the buttons. Well - call doDamage(); dontDoDamage() methods. And continue from there
Alex Volovoy
A: 

In Android, the syntax is different from .NET:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Hello!")
       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // Handle Ok
           }
       })
       .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // Handle Cancel
           }
       })
       .create();

Will get you a dialog with two buttons and you handle the button clicks with callbacks. You might be able to write some code to make the syntax more closely resemble .NET, but the dialog lifecycle is pretty intertwined with Activity, so in the end, it might be more trouble than it's worth. Additional dialog references are here.

Erich Douglass
Please see my EDIT 1 above =) thx =)
Ted
A: 

This is the simplest way:

new AlertDialog.Builder(this).setTitle("title").setMessage("message").create().show();
Cytown
Yes, but that doesnt solve the problem Im addressing I think, see my "EDIT 1" aboive in my question =) regards
Ted
doesn't stop execution
Marko
+2  A: 

In an attempt to optimize memory and performance dialogs in Android are asynchronous (they are also managed for this reason). Comming from the Windows world, you are used to modal dialogs. Android dialogs are modal but more like non-modal when it comes to execution. Execution does not stop after displaying a dialog.

The best description of Dialogs in Android I have seen is in "Pro Android" http://www.apress.com/book/view/1430215968

This is not a perfect explanation but it should help you to wrap your brain around the differences between Dialogs in Windows and Android. In Windows you want to do A, ask a question with a dialog, and then do B or C. In android design A with all the code you need for B and C in the onClick() of the OnClickListener(s) for the dialog. Then do A and launch the dialog. You’re done with A! When the user clicks a button B or C will get executed.

Windows
-------
A code
launch dialog
user picks B or C
B or C code
done!

Android
-------
OnClick for B code (does not get executed yet)
OnClick for C code (does not get executed yet)
A code
launch dialog
done!
user picks B or C
fupsduck
+3  A: 

Ted, you don't want to do this, really :) The biggest reason is that if you block the UI thread while you are displaying a Dialog, you will block the thread that's in charge of drawing and handling the events of your Dialog. Which means your dialog will be unresponsive. You will also cause ANRs if the user takes more than a few seconds to click the dialog.

Erich's answer is exactly what you need. I know it's not what you want, but that doesn't matter. We've designed Android to prevent developers from writing synchronous dialogs so you don't really have much of a choice.

Romain Guy
Hey Romain, thanks for the answer. I found [this thread](http://groups.google.com/group/android-developers/browse_thread/thread/f8f1ac25831adcf5/06f4f4868687fd6e?utoken=OFvxRDUAAACwwFf96muIoaCUrXmA7_-MBWr8sH0dHzLC3cUGCWl_v0ttVgZ6uIZjx_BoK4AXQSwmEzwNZNL90vKyYcNdWiMd) where some guy had the same problem. Sure, I dont have a choice, Im sure.
Ted
I have written applications where several modal Dialogs are presented after each other. the user has to answer all of them before proceeding. For example, there are a number of "control questions" that the User has to answer before proceeding. Let's say we have 3 such questions - that would be a complete mess to create in Android as I understand it. We need a bunch of pretty useless methods, one for each Dialog we are presenting for the user. The code gets "butchered" and split up, hard to follow and messy in general. That is a real shame I think =((note: that I like Android in other ways)
Ted
It's a mess because you are architecting your code in a way that's not meant to be with Android. Just do it *differently*. If you refuse to do so, it's your problem. For instance, instead of using 3 blocking dialogs (which I find to be a terrible and lazy UI by the way), why don't you have an Activity will all the questions and only when the user validates you start doing whatever your app is supposed to be doing.You asked a question, we've answered and so far the only thing you've been saying is that you don't like our answers. Sorry, but they won't change.
Romain Guy
+2  A: 

In Android Dialogs are asynchronous so you're going to have to structure your code a little differently.

So in C# your logic ran something like this in pseudocode:

void doSomeStuff() {
    int result = showDialog("Pick Yes or No");

    if (result == YES) {
        //do stuff for yes
    }
    else if (result == NO) {
        //do stuff for no
    }

    //finish off here
}

For Android it's going to have to be less neat. Think of it like so. You'll have an OnClickListener like this:

public void onClick(DialogInterface dialog, int whichButton) {
   if (whichButton == BUTTON_POSITIVE) {
      doOptionYes();
   }
   else if (whichButton == BUTTON_NEGATIVE) {
      doOptionNo();
   }
}

Which is then supported by the following methods:

void doOptionYes() {
    //do stuff for yes
    endThings();
}

void doOptionNo() {
    //do stuff for no
    endThings();
}

void endThings() {
    //clean up here
}

So what was one method is now four. It may not seem as neat but that's how it works I'm afraid.

Dave Webb
Thx Dave! Yes, that was what I have learned from all these answers. Unfortunately I have to say... Thx again =)
Ted