Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different views for spinner and spinner item?

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;
    }
like image 994
Martyn Avatar asked Sep 21 '11 11:09

Martyn


People also ask

What is a spinner view?

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.

What is spinner explain with suitable example?

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.

What is custom spinner in Android?

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.


3 Answers

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;
        }
    }
like image 166
Ian Avatar answered Sep 29 '22 08:09

Ian


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);
like image 26
louisbl Avatar answered Sep 29 '22 08:09

louisbl


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;
}
like image 27
Drew Avatar answered Sep 29 '22 07:09

Drew