0

I'm building a dialog with a spinner. When the dialog is done, it calls a method of the parent activity with a string argument - the argument being the string value that was selected.

My current approach:
I'm setting up the spinner's array adapter like so:

ArrayAdapter<String> adapter = 
    new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item,
    categoryNames);     

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(adapter);

categoryNames is a string array. When the dialog is done, the selected categoryName is used as the parameter to the method call on the parent activity.

What I really want to do:
What I actually want is to display a list of Category objects. The Category class has 2 properties - categoryId and categoryName. The spinner should still display the categoryNames in the drop-down view, but when the dialog is done, it should be able to unambiguously tell which Category was selected, and call the parent activity's callback method with the categoryId of the category that was selected.

There can be multiple Categoryies with the same categoryName.

Question: How to do the above?

jrharshath
  • 25,975
  • 33
  • 97
  • 127
  • While I already posted an answer, if the Category names aren't unique how will _the user_ tell the difference between with the same name (for example, "music" and "music")? – Sam Sep 20 '12 at 00:57
  • i've used the "category" and "categoryName" metaphor to simplify my use case :) – jrharshath Sep 20 '12 at 03:57

1 Answers1

10

There are a couple different way to do what you want:

  • Store the extra data in the adapter, like a SimpleAdapter, SimpleCursorAdapter, or custom one.
  • Use a Collection of custom objects instead of Strings, simply override the toString() method to present user readable Strings in the Spinner.

You seem to want to do the second option, so here's a generic example:

class Category {
    int id;
    String name;

    public Category(int id, String name) {
        this.id = id;
        this.name = name;
    }

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

Your ArrayAdapter is almost the same:

List<Category> categories = new ArrayList<Category>();
// Add new items with: categories.add(new Category(0, "Stack");

ArrayAdapter<Category> adapter = 
        new ArrayAdapter<Category>(getActivity(), android.R.layout.simple_spinner_item,
        categories);

...
mySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        Category category = parent.getItemAtPosition(position);
        Log.v("Example", "Item Selected id: " + category.id + ", name: " + category.name);
    }

    public void onNothingSelected(AdapterView<?> parent) {}
});
Sam
  • 86,580
  • 20
  • 181
  • 179
  • Hm, that presents a second challenge to me: when I pass in an array of `Category` objects to my dialog fragment (that's my dialog), how do I store it in the fragment's `arguments`? I could not find any `Bundle#setObjectArray()` method.. – jrharshath Sep 20 '12 at 00:59
  • Ha! I just answered [another question](http://stackoverflow.com/a/12503875/1267661) using Bundles to pass an ArrayList of custom objects. – Sam Sep 20 '12 at 01:06
  • Found your answer on parcelables very helpful :) For the record, I went with the toString() approach (though from a purist standpoint, that's not really the right solution). Would be great if you could point me to some examples of how to build a custom adapter though. – jrharshath Sep 21 '12 at 01:39
  • Android's Romain Guy discusses [custom adapters](http://www.google.com/events/io/2009/sessions/TurboChargeUiAndroidFast.html) at Google I/O 2009. I love source code myself, if you don't have your own copy grepcode.com is a great source. (You can speed read some tutorials from a search engine as well.) A custom adapter won't help you too much if you only display one String, but as your object grows your app will receive measurable benefits. – Sam Sep 21 '12 at 05:49