Using images in Spinner with ArrayAdapter

Sunday, January 9, 2011

In my experiments with android, I was challenged with creating a rating mechanism for a wine app that would use glasses (images) instead of traditional stars. In this article I will guid you through the process of using images in a spinner, to achieve the intended.







I was trying to use images in an Spinner, instead of regular text, but I was getting the following error message:  "ArrayAdapter requires the resource ID to be a TextView".

After a little bit of poking aroud, I realized I had to override both the getView and getDropDownView methods when extending ArrayAdapter.

Sample code:

MySpinnerAdapter class:

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MySpinnerAdapter extends ArrayAdapter {

 private int resource;
 private int mDropDownResource;
 public MySpinnerAdapter(Context context, int _resource, List objects) {
  super(context, _resource, objects);
  resource = _resource;
  mDropDownResource=_resource;
 }
 
  public MySpinnerAdapter(Context context, int _resource, int _dropDownResource, List objects) {
     super(context, _resource, objects);
     resource = _resource;
     mDropDownResource = _dropDownResource;
   }
 
 
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    return getView(position, convertView,parent, resource);
  }
  
  
  @Override
  public View getDropDownView(int position, View convertView, ViewGroup parent) {
    return getView(position, convertView,parent,mDropDownResource);
  }
  
  
  private View getView(int position, View convertView, ViewGroup parent, int _resourceId){
    LinearLayout view;
    
    Integer _rating = getItem(position);
    int rating = 0;
    if(_rating!=null){
      rating = _rating.intValue();
    }
    
    if(convertView==null){
      view = new LinearLayout(getContext());
      LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      vi.inflate(_resourceId, view, true);
    }else{
      view = (LinearLayout) convertView;
    }
    
    ImageView cb = null;
    int i=0;
    ///////////////
    //set rating
    while(i<=5){
      
      cb = (ImageView)view.findViewWithTag("star"+i);
      if(i<=rating){
        cb.setVisibility(View.VISIBLE);
      }else{
        cb.setVisibility(View.GONE);
      }      
      i++;
    }    
    return view;    
  }
}


XML layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/rating_root"
  style="?android:attr/spinnerDropDownItemStyle"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="?android:attr/listPreferredItemHeight">

  <ImageView android:id="@+id/star0"
    android:tag="star0"
    android:layout_width="wrap_content"
    android:padding="0dp"
    android:layout_height="wrap_content"
    android:visibility="gone"/>  


  <ImageView android:id="@+id/star1"
    android:src="@drawable/rat1"
    android:tag="star1"
    android:layout_width="16dp"
    android:padding="0dp"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:visibility="gone"/>
   
  <ImageView android:id="@+id/star2"
    android:src="@drawable/rat2"
    android:tag="star2"
    android:layout_width="16dp"
    android:padding="0dp"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:visibility="gone"/>

  <ImageView android:id="@+id/star3"
    android:src="@drawable/rat3"
    android:tag="star3"
    android:layout_width="16dp"
    android:padding="0dp"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:visibility="gone" />

  <ImageView android:id="@+id/star4"
    android:src="@drawable/rat4"
    android:tag="star4"
    android:layout_width="16dp"
    android:padding="0dp"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:visibility="gone" />

  <ImageView android:id="@+id/star5"
    android:src="@drawable/rat5"
    android:tag="star5"
    android:layout_width="16dp"
    android:padding="0dp"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:visibility="gone" />
</LinearLayout>


Action (Extract):

ArrayList al = new ArrayList();
    al.add(new Integer(0));
    al.add(new Integer(1));
    al.add(new Integer(2));
    al.add(new Integer(3));
    
    MySpinnerAdapter sa = new MySpinnerAdapter(this, R.layout.spinner_default, R.layout.spinner_drop_down, al);
    Spinner s = (Spinner)findViewById(R.id.wineRatingSpinner);
    s.setAdapter(sa);

No comments :