Android: Spinner-Like UI for Selecting Multiple Options
Download the source code files AndroidMultipleChoice.tar.gz (tar.gz, eclipse project)
Android includes a Spinner control that works very much like a desktop drop-down (or combo-box) control. Tapping a Spinner presents a list of options, and allows the user to select one from the list.
However, in building a small research app, I needed to allow users to select multiple items from the Spinner's list. From what I could see, though, the Spinner class is not capable of doing this, so I built a small throwaway app that implements this oft-requested functionality.
Getting Started
Spin up a new Android application in Eclipse, creating an activity named MultipleChoiceActivity. For reference, I'm targeting the Google Android 2.1 APIs (Level 7).
Once the project is created, open up and edit the main.xml
file to display a simple label and button. I've used a Button instead of a Spinner as we can change the button's label to indicate which options have been selected:
<!-- res/main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="5dip">
<TextView
android:text="Select Colours"
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dip" />
<Button
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="- None Selected -"
android:id="@+id/select_colours"
android:padding="5dip" />
</LinearLayout>
Building the Activity
For this example, I'm using a hard-coded list of colours here in this example (rather than, for example, hooking up to a database). Start by hooking up the interface to properties in MultipleChoiceActivity.java
:
// src/com/example/multiple_choice/MultipleChoiceActivity.java
// ... package, imports ...
public class MultipleChoiceActivity extends Activity implements OnClickListener {
protected Button selectColoursButton;
protected CharSequence[] colours = { "Red", "Green", "Blue", "Yellow", "Orange", "Purple" };
protected ArrayList<CharSequence> selectedColours = new ArrayList<CharSequence>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
selectColoursButton = (Button) findViewById(R.id.select_colours);
selectColoursButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.select_colours:
// TODO: Show the colours dialog
break;
default:
break;
}
}
}
With that code, your button is now hooked up to listen for clicks. The colours
array is a simple list of colours that will be displayed when we click the button. The selectedColours
ArrayList is a dynamic array of the colours that have been selected. Using ArrayList lets us easily add and remove colours when the user changes the selection.
Try running the app in the Android emulator (or on a device) to check that everything works so far.
Displaying the Options
Next, we'll use Android's AlertDialog to let us display the list of colours, and allow the user to make selections. AlertDialog comes with built-in functionality to allow multiple selections, and automatically adds checkboxes to our list interface.
Add the following method to MultipleChoiceActivity.java
:
// src/com/example/multiple_choice/MultipleChoiceActivity.java
protected void showSelectColoursDialog() {
boolean[] checkedColours = new boolean[colours.length];
int count = colours.length;
for(int i = 0; i < count; i++)
checkedColours[i] = selectedColours.contains(colours[i]);
DialogInterface.OnMultiChoiceClickListener coloursDialogListener = new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if(isChecked)
selectedColours.add(colours[which]);
else
selectedColours.remove(colours[which]);
onChangeSelectedColours();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Colours");
builder.setMultiChoiceItems(colours, checkedColours, coloursDialogListener);
AlertDialog dialog = builder.create();
dialog.show();
}
showSelectColoursDialog
is the method that will be called when tapping the button. It starts by walking through the colours
array and checking which colours are already in the selectedColours
ArrayList. The results get stored in an array of booleans (checkedColours
) that will be used by the AlertDialog to determine which items in the list are to be checked.
Next, we build a DialogInterface.OnMultiChoiceClickListener
that will be invoked when the user checks or unchecks a colour in the list. Depending on the state of the check box (supplied via the isChecked
parameter), we add or remove the colour from the selectedColours
ArrayList.
Notice that when the listener is finished, we call an as-yet undefined method, onChangeSelectedColours
. This will be a callback method that we'll use to update the button's label:
// src/com/example/multiple_choice/MultipleChoiceActivity.java
protected void onChangeSelectedColours() {
StringBuilder stringBuilder = new StringBuilder();
for(CharSequence colour : selectedColours)
stringBuilder.append(colour + ",");
selectColoursButton.setText(stringBuilder.toString());
}
This simple callback method just walks through the ArrayList of selected colours, and builds a string containing the name of each colour.
Finally, all that's left to do is hook up our button to call showSelectColoursDialog
in the onClick
method we overrode earlier:
// src/com/example/multiple_choice/MultipleChoiceActivity.java
@Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.select_colours:
showSelectColoursDialog();
break;
default:
break;
}
}
With everything hooked up, it's time to test out the app. Run the emulator (or install to a device), tap the button and you'll be able to select multiple colours from the list. If you tap the back button, the list will close, and your button's label will have updated to show the colours you tapped. Try tapping the button again, and your previously selected colours will still be checked.
Summary
Hopefully this simple example will be useful to anyone looking to implement multiple-choice options. It would be nice to use the Spinner gadget rather than a Button, perhaps by subclassing Spinner and overriding it's click handler and label drawing methods. I haven't tried this - let me know in the comments if you decide to give it a go.
👋 Thanks for reading - I hope you enjoyed this post. If you find it helpful and want to support further writing and tutorials like this one, please consider supporting my work with a coffee!
Support ☕️