Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating Spinner with Enum that has string resource

I have an enum that has a property that maps to a string resource id, like so:

public enum MyEnum{

  FIRST(1,R.string.first_enum_desc),
  SECOND(2,R.string.second_enum_desc);

  private int mId;
  private int mDescriptionResourceId;

  private MyEnum(id,descriptionResourceId) {
      mId = id;
      mDescriptionResourceId = descriptionResourceId;
  }

  public toString(context){
      return context.getString(mDescriptionResourceId);
  }
}

I want to populate a spinner with the enum, the problem is simply using an adapter of my type:

Spinner spinner;
spinner.setAdapter(new ArrayAdapter<MyEnum>(this, android.R.layout.simple_spinner_item, MyEnum.values()));

I don't get the string resource description as the adapter implicitly calls toString(), which returns the enum name. I'm not sure how to proceed here. No matter what I need the Context to get the string values. Could someone suggest the best way to achieve what I am looking for? I just need a point in the right direction. Any advice would be appreciated. Thanks much!

like image 611
TheMethod Avatar asked Aug 18 '14 17:08

TheMethod


2 Answers

You should build your own ArrayAdapter. And then override the methods getView() and getDropDownView.

public class MyAdapter extends ArrayAdapter<MyEnum> {

    public MyAdapter (Context context) {
        super(context, 0, MyEnum.values());
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         CheckedTextView text= (CheckedTextView) convertView;

         if (text== null) {
             text = (CheckedTextView) LayoutInflater.from(getContext()).inflate(android.R.layout.simple_spinner_dropdown_item,  parent, false);
         }

         text.setText(getItem(position).getDescriptionResourceId());

         return text;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        CheckedTextView text = (CheckedTextView) convertView;

        if (text == null) {
            text = (CheckedTextView) LayoutInflater.from(getContext()).inflate(android.R.layout.simple_spinner_dropdown_item,  parent, false);
        }

        text.setText(getItem(position).getTitle());

        return text;
    }
}
like image 75
bbrakenhoff Avatar answered Oct 31 '22 06:10

bbrakenhoff


The easiest way to retrieve your enum provided its view position, or its item position is getting its position : as you pass the values of the enum, they'll be displayed in the order they're declared. For example in an OnItemClickListener :

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    MyEnum value = MyEnum.values()[position];
    ...
}

Another solution would be to retrieve the text of the view then parse the enum using Enum.valueOf, but this requires to know the id of the TextView that displays the item and seems to complicated compared to the first solution. Something like :

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    String text = ((TextView) parent.findViewById(R.id.mytextview)).getText();
    MyEnum value = MyEnum.valueOf(text);
}

And last, you can also retrieve the enum from the adapter and cast it, for example like this :

MyEnum.class.cast(myListView.getAdapter().getItem(position))
like image 2
Antoine Marques Avatar answered Oct 31 '22 06:10

Antoine Marques