Igor Igor - 11 months ago 60
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 Source

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).