Mike Classic

Android Archives

Android: Populating Spinner With Strings And Id

Jul/25/2014

Ever needed to reference an object when selected in a default implementation of a Spinner widget? Most likely you have. Your Spinner is populated with an ArrayList of strings, so how can you map it to the object it represents?

The user may select a student's name, but how do we preserve the key to look it up in the original collection upon selection in the Spinner?

Thanks to a kind soul on StackOverflow, here is a simple solution, which doesn't resort to iterating through all Student objects with the first name that matches the user's selection.

Let's assume your original collection of students is a HashMap, defined with an Integer key and a String value. So let's pretend it looks like this:

HashMap<Integer, String> mStudents = new HashMap<Integer, String>() {{
    put(0, "Bob");
    put(1, "Christine");
}};

This way you don't have to keep the ArrayList in a certain order in the Spinner, and you don't even have to rely on Integer-based keys either.

Well the Spinner is only going to accept an ArrayList of String values. So how can we convert this to an ArrayList while preserving our keys for lookup later?

private static class StringWithTag {
  public String string;
  public Object tag;

  public StringWithTag(String string, Object tag) {
    this.string = string;
    this.tag = tag;
  }

  @Override
  public String toString() {
    return string;
  }
}

Instead of passing ArrayList<String>, you pass instances of this class to the ArrayAdapter class which will be attached to the Spinner.

The Spinner will execute .toString() on every item in the collection, to which we've overridden that method to display the String-based value accordingly.

Spinner spinner = (Spinner) v.findViewById(R.id.spinner);
/* Create your ArrayList collection using StringWithTag instead of String. */
List<StringWithTag> itemList = new ArrayList<StringWithTag>();

/* Iterate through your original collection, in this case defined with an Integer key and String value. */
for (Entry<Integer, String> entry : mStudents.entrySet()) {
  Integer key = entry.getKey();
  String value = entry.getValue();

  /* Build the StringWithTag List using these keys and values. */
  itemList.add(new StringWithTag(value, key));
}

/* Set your ArrayAdapter with the StringWithTag, and when each entry is shown in the Spinner, .toString() is called. */
ArrayAdapter<StringWithTag> spinnerAdapter = new ArrayAdapter<StringWithTag>(getActivity(), android.R.layout.simple_spinner_item, itemList);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);

And this is how we can retrieve it upon item selection.

public void onItemSelected(AdapterView<?> parent, View view, int position,
    long id) {
    StringWithTag swt = (StringWithTag) parent.getItemAtPosition(position);
    Integer key = (Integer) swt.tag;
    doSomethingWith(mStudents.get(key));
}