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;
}
Spinners provide a quick way to select one value from a set. In the default state, a spinner shows its currently selected value. Touching the spinner displays a dropdown menu with all other available values, from which the user can select a new one. You can add a spinner to your layout with the Spinner object.
Android Spinner is a view similar to the dropdown list which is used to select one option from the list of options. It provides an easy way to select one item from the list of items and it shows a dropdown list of all values when we click on it.
Spinner is a widget that is used to select an item from a list of items. When the user tap on a spinner a drop-down menu is visible to the user. In this article, we will learn how to add custom spinner in the app.
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;
}
}
Although this is an old question, I stumbled upon trying to solve the same problem.
I use setDropDownViewResource:
Spinner mySpinner = (Spinner) mView.findViewById(R.id.mySpinner);
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(...);
myAdapter.setDropDownViewResource(R.layout.my_simple_spinner_dropdown_item);
mySpinner.setAdapter(adapter);
Actually, getting different Views for expanded (opened) and collapsed (closed) Spinner is as simple as overriding getView and getDropdownView methods of your adapter.
getView(int position, View convertView, ViewGroup parent) will produce all the Views that will be used to display a selected item when the Spinner is collapsed.
getDropDownView(int position, View convertView, ViewGroup parent) gets called when you click on a Spinner to expand it and display a dropdown list of your items. You can either call getView from this method (if your items in expanded and collapsed states are similar), or produce a different View for the item in your dropdown list.
It would be nice if you override both these methods anyway (even if your getDropdownView just calls getView with the same arguments). And do not forget to use your convertView parameter - it is here for a purpose of optimisation (to reuse existing Views instead of inflating/creating them every time):
public View getView(int position, View convertView, ViewGroup parent) {
...
if(convertView == null){
convertView = View.inflate(getContext(),
R.layout.dropdown_category_color, null);
}
//...do your stuff with your View
return convertView;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With