Igor Igor - 7 days ago 5
Android Question

Custom ArrayAdapter setBackground in getView

I'm working on a ListActivity which will display a bunch of numbers (weights). I would like to change the background of a specific row in the ListView. To do this I have created a custom implementation of the ArrayAdapter class and have overridden the getView method. The adapter accepts a list of numbers and sets the background of the row with the number 20 to yellow (for simplicity reasons).

public class WeightListAdapter extends ArrayAdapter<Integer> {

private List<Integer> mWeights;

public WeightListAdapter(Context context, List<Integer> objects) {
super(context, android.R.layout.simple_list_item_1, objects);

mWeights = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);

int itemWeight = mWeights.get(position);
if (itemWeight == 20) {
v.setBackgroundColor(Color.YELLOW);
}
return v;
}

}


The problem is that not only the row with the number 20 gets the yellow background but also the row with the number 0 (the first row that is) and I'm not sure why this is so.

Am I doing something wrong in the getView method (like calling the super method)? My reasoning for the implementation is: All the returned views should be the same (that's why I'm calling the super method) only the view fitting the if criteria should be changed.

Thanks for your help!

Answer

I did a bit of research to find out how this should be done properly.

I'm writing this down for the others with the same problem, as I guess this is the proper way how to do it. Please, let me know, if I am mistaken or if this solution has any flaws I'm not seeing.

public class WeightListAdapter extends ArrayAdapter<Integer> {

  private static final int TYPE_COUNT = 2;
  private static final int TYPE_ITEM_COLORED = 1;
  private static final int TYPE_ITEM_NORMAL = 0;

  public WeightListAdapter(Context context, List<Integer> objects) {
    super(context, android.R.layout.simple_list_item_1, objects);
  }

  @Override
  public int getViewTypeCount() {
    return TYPE_COUNT;
  }

  @Override
  public int getItemViewType(int position) {
    int item = getItem(position);

    return (item == 30) ? TYPE_ITEM_COLORED : TYPE_ITEM_NORMAL;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View v = super.getView(position, convertView, parent);
    switch (getItemViewType(position)) {
    case TYPE_ITEM_COLORED:
      v.setBackgroundColor(Color.YELLOW);
      break;
    case TYPE_ITEM_NORMAL:
      break;
    }

    return v;

  }
}

Apparently the base class already implements the logic ensuring the correct convertView is passed to the getView method (based on the getViewItemType and getViewTypeCount methods).