I have an alert dialog with a single-choice list and two buttons: an OK
button and a cancel
button. The code below show how I implemented it.
private final Dialog createListFile(final String[] fileList) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Compare with:"); builder.setSingleChoiceItems(fileList, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(TAG,"The wrong button was tapped: " + fileList[whichButton]); } }); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) {} }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) {} }); return builder.create(); }
My goal is to obtain the name of the selected radio button when the OK
button is tapped. I tried to save the string in a variable, but inside an inner class it is possible to access only final variables. Is there a way to avoid using a final variable to store the selected radio button?
AlertDialog is a lightweight version of a Dialog. This is supposed to deal with INFORMATIVE matters only, That's the reason why complex interactions with the user are limited. Dialog on the other hand is able to do even more complex things .
The way to make a checkbox list is to use setMultiChoiceItems . // setup the alert builder AlertDialog. Builder builder = new AlertDialog. Builder(context); builder.
A simple dialog containing an DatePicker . This class was deprecated in API level 26.
Alert Dialog shows the Alert message and gives the answer in the form of yes or no. Alert Dialog displays the message to warn you and then according to your response the next step is processed. Android Alert Dialog is built with the use of three fields: Title, Message area, Action Button.
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();
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With