Is there any way I can set a different view for the closed spinner view and the spinner item view?
I assume that the resource id used in the ArrayAdapter
would be used for the closed item view, as well as the item views, so I extended the ArrayAdapter
and defined the getView
which uses a different resource, but the resource id in the call to the super constructor doesn't seem to be used ever, only the resource id used in getView
seems to be used
In the Spinner.java code it states:
A spinner adapter allows to define two different views: one that shows the data in the spinner itself and one that shows the data in the drop down list when the spinner is pressed.
but it doesn't seem possible given the code.
Anyway - my code:
public class CustomArrayAdapter <T> extends ArrayAdapter<T> {
int itemViewResourceId;
private LayoutInflater inflater;
ViewPopulator<T> viewPopulator;
private List<T> objects;
public CustomArrayAdapter(Context context, int textViewResourceId, int itemViewResourceId, ViewPopulator<T> viewPopulator, List<T> objects) {
super(context, textViewResourceId, objects);
inflater = LayoutInflater.from(context);
this.viewPopulator = viewPopulator;
this.itemViewResourceId = itemViewResourceId;
this.objects = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null || convertView.getTag() == null) {
// new view - populate
convertView = inflater.inflate(itemViewResourceId, parent, false);
convertView.setTag(new Object());
}
viewPopulator.populateView(position, convertView, parent, objects.get(position));
return convertView;
}
}
public abstract class ViewPopulator<T> {
public abstract void populateView(int position, View convertView, ViewGroup parent, T item);
}
called with:
CustomArrayAdapter<T> typeAdapter = new CustomArrayAdapter<T>(context, R.layout.list_item, R.layout.list_item_big, new ViewPopulator<T>() {
@Override
public void populateView(int position, View convertView, ViewGroup parent, T item) {
((TextView) convertView.findViewById(R.id.list_item)).setText(position + " - " + item.getName());
}
}, itemsByType.get(type));
** EDIT **
The resource id used is the itemViewResourceId
defined in the getView
method -
adding a new method to CustomArrayAdapter
, overriding getDropDownView
as below give me the same results of the itemViewResourceId
being used for all the styling, and the textViewResourceId
not being used at all. However, removing the getView
results in the textViewResourceId
being used - hence I don't think that getDropDownView
actually does anything:
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if(convertView == null || convertView.getTag() == null) {
// new view - populate
convertView = inflater.inflate(itemViewResourceId, parent, false);
convertView.setTag(new Object());
}
viewPopulator.populateView(position, convertView, parent, objects.get(position));
return convertView;
}
If you implement SpinnerAdapter
does that help?
The following code works for me:
private class CustomSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
String[] values;
Context context;
public NumberSpinnerAdapter(String[] values) {
this.values = values;
this.context = context;
}
@Override
public int getCount() {
return values.length;
}
@Override
public Object getItem(int position) {
return values[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) View.inflate(context, android.R.layout.simple_spinner_item, null);
textView.setText(values[position]);
return textView;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) View.inflate(context, android.R.layout.simple_spinner_dropdown_item, null);
textView.setText(values[position]);
return textView;
}
}