android – How can I set the order of the positive and negative buttons in AlertDialog?-ThrowExceptions

Exception or error:

Why I want to do this is another discussion entirely, but I need to figure out the best way to make all my alert dialogs have the positive button on the right side. Note that in version 3.0 and below the buttons normally appear as OK / Cancel and in 4.0 and above it is Cancel / OK. I want to force my application to use Cancel / OK in the simplest way possible. I have a lot of AlertDialogs in the application.

How to solve:

Unfortunately, I don’t believe you can. However, to quote the documentation:

Note: You can only add one of each button type to the AlertDialog. That is, you cannot have more than one “positive” button. This limits the number of possible buttons to three: positive, neutral, and negative. These names are technically irrelevant to the actual functionality of your buttons, but should help you keep track of which one does what.

So you can turn the different buttons into whatever you want. What you’re seeing here is the order having switched (ordering from this answer):

  • On devices prior to ICS, the button order (left to right) was POSITIVE – NEUTRAL – NEGATIVE.
  • On newer devices using ICS, the button order (left to right) is now NEGATIVE – NEUTRAL – POSITIVE.

You might try checking the Build.VERSION and using that to decide which button is which at runtime.

###

this is my solution. It is work for me.

    // Show alertDialog after building
    AlertDialog alertDialog = createAlertDialog(context);
    alertDialog.show();
    // and find positiveButton and negativeButton
    Button positiveButton = (Button) alertDialog.findViewById(android.R.id.button1);
    Button negativeButton = (Button) alertDialog.findViewById(android.R.id.button2);
    // then get their parent ViewGroup
    ViewGroup buttonPanelContainer = (ViewGroup) positiveButton.getParent();
    int positiveButtonIndex = buttonPanelContainer.indexOfChild(positiveButton);
    int negativeButtonIndex = buttonPanelContainer.indexOfChild(negativeButton);
    if (positiveButtonIndex < negativeButtonIndex) {
        // prepare exchange their index in ViewGroup
        buttonPanelContainer.removeView(positiveButton);
        buttonPanelContainer.removeView(negativeButton);
        buttonPanelContainer.addView(negativeButton, positiveButtonIndex);
        buttonPanelContainer.addView(positiveButton, negativeButtonIndex);
    }

###

You can extend the AlertDialog.Builder to force the order:

public class MyDialog extends AlertDialog.Builder {

    public MyDialog(Context arg0) {
        super(arg0);
    }

    @Override
    public Builder setPositiveButton(CharSequence text, OnClickListener listener) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return super.setNegativeButton(text, listener);
        } else {
            return super.setPositiveButton(text, listener);
        }

    }

    @Override
    public Builder setNegativeButton(CharSequence text, OnClickListener listener) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return super.setPositiveButton(text, listener);
        } else {
            return super.setNegativeButton(text, listener);
        }
    }

}

###

I’ve created a solution to force order of buttons for any Android version on any device.

The idea is that we can get list of buttons of dialog in order they appear on screen and set text and actions in order we want. It guarantees that we would have same order on any device.

Please check my GitHub repository

Here is example of creating and showing dialog:

 new FixedOrderDialogFragment.Builder()
    .setLeftButtonText(R.string.left)
    .setCenterButtonText(R.string.center)
    .setRightButtonText(R.string.right)
    .setDefaultButton(FixedOrderDialogFragment.BUTTON_RIGHT)
    .setMessage(R.string.message)
    .setTitle(R.string.app_name)
    .create()
 .show(getSupportFragmentManager(), "DEMO");

Please note that owner Activity should implement FixedOrderDialogFragment.FixedOrderDialogListener to be able restore dialog state on Activity re-creation.

###

I figured I could just set the text for the positive button to Cancel and the negative to OK but it turns out they are in alphabetical order.

###

  • In AlertDialog buttonPanel,the three buttons sort by [Neutral] [Negative] [Positive]
  • then you can set buttons like following codes

    builder.setNeutralButton(“Negative”,listener);

    builder.setNegativeButton(“Neutral”,listener);

    builder.setPositiveButton(“Positive”,listener);

###

Sometimes completely different perspectives are the solution to a problem, the HI-user culture.

  • In Win32 an OK and a Cancel button is absolutely necessary or the dialog will not work.
  • In Android the HI is quite different because of the existence of the OS “Back” button (onBackPressed() that could also be overridden, ESC on attached physical keyboards) in the operative system HI.

    • There is no need for a Negative/cancel button in most cases.
    • So most dialog are enough with the Positive button
    • Then there are no button order issue, the positive button is alone?
    • If you are in an edit field set it to edittext.setSingleLine(); and enter will move focus to the single positive button. Enter again and its positive button pressed.
    • If the user wants to push Cancel, he presses the OS “Back” button (As a developer we do not need to explain the core of the OS HI policy to the user, that is an issue of the OS issuer. We just leave the Android dialog without a Cancel button.)

Leave a Reply

Your email address will not be published. Required fields are marked *