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 View
s 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 View
s 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