Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 491
Igor Avatar asked Oct 24 '10 14:10

Igor


People also ask

How to set ArrayAdapter in Android?

Go to app > res > layout > right-click > New > Layout Resource File and create a new layout file and name this file as item_view. xml and make the root element as a LinearLayout. This will contain a TextView that is used to display the array objects as output.

How to set Array adapter?

To use a basic ArrayAdapter , you just need to initialize the adapter and attach the adapter to the ListView. First, we initialize the adapter: ArrayAdapter<String> itemsAdapter = new ArrayAdapter<String>(this, android. R.


2 Answers

Android's view is re-use a component for each row. I got this problem too.

like image 34
apichaic Avatar answered Sep 28 '22 04:09

apichaic


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

like image 109
Igor Avatar answered Sep 28 '22 05:09

Igor