How to select a entry in AlertDialog with single choice checkbox android?

Solution 1:

Using a final variable obviously won't work (since it can only be assigned once, at declaration time). So-called "global" variables are usually a code smell (especially when they become part of an Activity class, which is usually where AlertDialogs are created). The cleaner solution is to cast the DialogInterface object to an AlertDialog and then call getListView().getCheckedItemPosition(). Like this:

new AlertDialog.Builder(this)
        .setSingleChoiceItems(items, 0, null)
        .setPositiveButton(R.string.ok_button_label, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
                int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
                // Do something useful withe the position of the selected radio button
            }
        })
        .show();

Solution 2:

This has been answered just fine, but I keep finding this answer from Google and I wanted to share a non-anonymous class solution. I prefer reusable classes myself and may be helpful to others.

In this example, I'm using a DialogFragment implementation and retrieving a value via a callback method.

The callback method to get values from a Dialog can be done by creating a public interface

public interface OnDialogSelectorListener {
    public void onSelectedOption(int selectedIndex);
}

Also the DialogFragment implements DialogInterface.OnClickListener which means you can register the class you've implemented as the OnClickListener for the DialogFragment that is being created.

For example

public Dialog onCreateDialog(Bundle savedInstanceState) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());

    builder.setTitle(R.string.select);
    builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);
    builder.setPositiveButton(R.string.ok, this);
    builder.setNegativeButton(R.string.cancel, this);
    return builder.create();
}

The line

builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);

Creates a choice dialog with the options from a resource array stored in mResourceArray. This also preselects an option index from what is stored in mSelectedIndex and finally it sets this itself as the OnClickListener. (See full code at the end if this paragraph is a tad confusing)

Now, the OnClick method is where you grab the value that comes from the dialog

@Override
public void onClick(DialogInterface dialog, int which) {

    switch (which) {
        case Dialog.BUTTON_NEGATIVE: // Cancel button selected, do nothing
            dialog.cancel();
            break;

        case Dialog.BUTTON_POSITIVE: // OK button selected, send the data back
            dialog.dismiss();
            // message selected value to registered callbacks with the
                    // selected value.
            mDialogSelectorCallback.onSelectedOption(mSelectedIndex);
            break;

        default: // choice item selected
                    // store the new selected value in the static variable
            mSelectedIndex = which;
            break;
    }
}

What happens here is when an item is selected, it's stored in a variable. If the user clicks the Cancel button, no update is sent back and nothing changes. If the user clicks the OK button, it returns the value to the Activity that created it via the callback created.

As an example, here is how you would create the dialog from a FragmentActivity.

final SelectorDialog sd = SelectorDialog.newInstance(R.array.selector_array, preSelectedValue);
sd.show(getSupportFragmentManager(), TAG);

Here, the resource array _R.array.selector_array_ is an array of strings to show in the dialog and preSelectedValue is the index to select on open.

Finally, your FragmentActivity will implement OnDialogSelectorListener and will receive the callback message.

public class MyActivity extends FragmentActivity implements OnDialogSelectorListener {
// ....

    public void onSelectedOption(int selectedIndex) {
        // do something with the newly selected index
    }
}

I hope this is helpful to someone, as it took me MANY attempts to understand it. A full implementation of this type of DialogFragment with a callback is here.

public class SelectorDialog extends DialogFragment implements OnClickListener {
    static final String TAG = "SelectorDialog";

    static int mResourceArray;
    static int mSelectedIndex;
    static OnDialogSelectorListener mDialogSelectorCallback;

    public interface OnDialogSelectorListener {
        public void onSelectedOption(int dialogId);
    }

    public static DialogSelectorDialog newInstance(int res, int selected) {
        final DialogSelectorDialog dialog  = new DialogSelectorDialog();
        mResourceArray = res;
        mSelectedIndex = selected;

        return dialog;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            mDialogSelectorCallback = (OnDialogSelectorListener)activity;
        } catch (final ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnDialogSelectorListener");
        }
    }

    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());

        builder.setTitle(R.string.select);
        builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);
        builder.setPositiveButton(R.string.ok, this);
        builder.setNegativeButton(R.string.cancel, this);
        return builder.create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {

        switch (which) {
            case Dialog.BUTTON_NEGATIVE:
                dialog.cancel();
                break;

            case Dialog.BUTTON_POSITIVE:
                dialog.dismiss();
                // message selected value to registered calbacks
                mDialogSelectorCallback.onSelectedOption(mSelectedIndex);
                break;

            default: // choice selected click
                mSelectedIndex = which;
                break;
        }

    }
}

Question from a comment How to call this from a Fragment instead of an Activity.

First make a few changes to the DialogFragment.

Remove the onAttach event since that's not the easiest way in this scenario.

Add a new method to add a reference to the callback

public void setDialogSelectorListener (OnDialogSelectorListener listener) {
    this.mListener = listener;
}

Implement the listener in your Fragment

public class MyFragment extends Fragment implements SelectorDialog.OnDialogSelectorListener {
// ....

    public void onSelectedOption(int selectedIndex) {
        // do something with the newly selected index
    }
}

Now create a new instance and pass in a reference to the Fragment to use it.

final SelectorDialog sd = SelectorDialog.newInstance(R.array.selector_array, preSelectedValue);
// this is a reference to MyFragment
sd.setDialogSelectorListener(this);
// mActivity is just a reference to the activity attached to MyFragment
sd.show(this.mActivity.getSupportFragmentManager(), TAG);

Solution 3:

final CharSequence[] choice = {"Choose from Gallery","Capture a photo"};

int from; //This must be declared as global !

AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setTitle("Upload Photo");
alert.setSingleChoiceItems(choice, -1, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (choice[which] == "Choose from Gallery") {
            from = 1;
        } else if (choice[which] == "Capture a photo") {
            from = 2;
        }
    }
});
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (from == 0) {
            Toast.makeText(activity, "Select One Choice", 
                        Toast.LENGTH_SHORT).show();
        } else if (from == 1) {
            // Your Code
        } else if (from == 2) {
            // Your Code
        }
    }
});
alert.show();

Solution 4:

As others have pointed out, implementation 'com.google.android.material:material:1.0.0' it is more simply

Refere this material guide for more. https://material.io/develop/android/docs/getting-started/

CharSequence[] choices = {"Choice1", "Choice2", "Choice3"};
boolean[] choicesInitial = {false, true, false};
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getContext())
    .setTitle(title)
    .setPositiveButton("Accept", null)
    .setNeutralButton("Cancel", null)
    .setMultiChoiceItems(choices, choicesInitial, new DialogInterface.OnMultiChoiceClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which, boolean isChecked) {

      }
    });
alertDialogBuilder.show();

enter image description here