-1

I asked this question yesterday (http://stackoverflow.com/questions/7392321/how-do-you-disable-a-button-inside-of-an-alertdialog) and modified my code accordingly... this morning I ran the code in an emulator and received an NPE. Here is the code:

public void monster() {
        int playerint = settings.getPlayerInt();
        int monsterint = settings.getMonsterInt();



        AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
        alertbox.setMessage("You have Encountered a Monster");

        alertbox.setPositiveButton("Fight!",
                new DialogInterface.OnClickListener() {

                    // do something when the button is clicked
                    public void onClick(DialogInterface arg0, int arg1) {
                        createMonster();
                        fight();

                    }
                });

        alertbox.setNeutralButton("Try to Outwit",
                new DialogInterface.OnClickListener() {

                    // do something when the button is clicked
                    public void onClick(DialogInterface arg0, int arg1) {
                        // This should not be static
//                      createTrivia();
                        trivia();

                    }
                });

        // Return to Last Saved CheckPoint
        alertbox.setNegativeButton("Run Away!",
                new DialogInterface.OnClickListener() {

                    // do something when the button is clicked
                    public void onClick(DialogInterface arg0, int arg1) {
//                      runAway();
                    }
                });

THIS IS WHERE THE PROBLEM STARTS

// show the alert box
            alertbox.show();
            AlertDialog dialog = alertbox.create();
            Button button = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
            if(monsterint > playerint) {
                button.setEnabled(false);
            }
        }

Anyone know what I am doing wrong?

Frank Bozzo
  • 15,033
  • 6
  • 25
  • 29

4 Answers4

10

You have two problems. The first is that you should be calling show() and create() separately like that. What you've actually done is implicitly create one AlertDialog and display it with alertbox.show(), and then right below it create a second AlertDialog that you are using to manipulate the button. Let's try to keep the direct calls to the Builder at a minimum.

Also, and the more direct reason for your NPE crash, in AlertDialog land the buttons themselves don't actually get created until the AlertDialog is prepared for display (basically, after AlertDialog.show() is called...again, not to be confused with the AlertDialog.Builder.show() method). In order to use AlertDialog for your purposes, you need to obtain and manipulate the button state after displaying the dialog. Here is a modification of your final code section that fixes this:

//Create the AlertDialog, and then show it
AlertDialog dialog = alertbox.create();
dialog.show();
//Button is not null after dialog.show()
Button button = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
if(monsterint > playerint) {
    button.setEnabled(false);
}

HTH

devunwired
  • 62,780
  • 12
  • 127
  • 139
  • Thank you for you in depth answer... Unfortunately, I am still getting an NPE crash even after these modifications! Any ideas? – Frank Bozzo Sep 14 '11 at 21:15
2

The trick is that you need to use the AlertDialog object retuned by AlertDialog.Builder.show() method. No need to call AlertDialog.Builder.create().

Example:

        AlertDialog dialog = alertbox.show();
        if(monsterint > playerint) {
            Button button = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
            button.setEnabled(false);
        }
Ashraf Sousa
  • 246
  • 3
  • 4
1

EDIT

At first I thought the code should read:

        AlertDialog dialog = alertbox.create();
        Button button = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
        if(monsterint > playerint) {
            button.setEnabled(false);
        }

        dialog.show();

And I would expect this to work, however no matter how you cook this piece of code, the call to getButton(int which) always returns null.

There doesn't seem to be any sensible reason for this. I am tempted to say that this is a bug in the API. I targeted it for API level 8.

UPDATE

Congratulations you have discovered Android Bug #6360 see comment #4 for a workaround

Also you could take a look at a possible indirect duplicate of this question

And the solution is to call getButton after dialog.show():

        AlertDialog dialog = alertbox.create();

        dialog.show();

        Button button = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
        if(monsterint > playerint) {
            button.setEnabled(false);
        }
Community
  • 1
  • 1
Moog
  • 10,193
  • 2
  • 40
  • 66
  • That's actually not true. Calling `show()` directly on an `AlertDialog.Builder` object implicitly calls its `create()` method and then displays the result. – devunwired Sep 13 '11 at 21:55
  • Thanks for pointing it out ... learn something new every day. I have updated my answer – Moog Sep 13 '11 at 22:51
  • Code is still generating an NPE – Frank Bozzo Sep 14 '11 at 21:19
  • 1
    @FrankBozzo I tested the code ... and it is running infront of my own eyes ... so you must have missed something. NOTE: the correct code calls `dialog.getButton(..)` AFTER `dialog.show()` – Moog Sep 14 '11 at 21:29
-1

i tryed these code and it work's you need to hid first show ok

AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
        alertbox.setMessage("You have Encountered a Monster");
        alertbox.setPositiveButton("asdasd", null);

        alertbox.show();
        alertbox.setPositiveButton("", null);
        alertbox.show();
PedroAGSantos
  • 2,336
  • 2
  • 17
  • 34
  • @Frank Bozzo i was just showing how to hide the button :( and i was wrong but Merlin is wrong to `button.setVisibility(View.GONE);` – PedroAGSantos Sep 13 '11 at 15:19
  • @FrankBozzo I have updated my answer and given a complete explanation as to why this occurs – Moog Sep 13 '11 at 22:58