1

Im making a little shopping list app. In the app, if an item in a list view has been marked as bought it gets crossed off with a line. My problem is that when the list is first displayed, if there are any items that are marked as bought in the list, the first item will appear as being marked as bought(will have a line through it) even if its not.

image example of problem

if no items are marked as bought then the first item displays as it should

Code for my array adapter

public class ListAdapter extends BaseAdapter{
Context context;
ArrayList<List_Item> items;

public ListAdapter(Context context, ArrayList<List_Item> list){
    this.context = context;
    items = list;
}

@Override
public int getCount() {
    if(items != null)
        return items.size();
    else
        return 0;
}

@Override
public Object getItem(int index) {
    return items.get(index);
}

@Override
public long getItemId(int index) {
    return 0;
}

@Override
public View getView(int pos, View convertView, ViewGroup parent) {
    View view = convertView;
    Holder holder = new Holder();

    if(convertView == null){
        view = LayoutInflater.from(context).inflate(R.layout.complex_list_item, parent, false);
    }

    holder.main = (TextView)view.findViewById(R.id.LItextView1);
    holder.second = (TextView)view.findViewById(R.id.LItextView2);

    List_Item item = items.get(pos);

    holder.main.setText(item.name);
    holder.second.setText(item.qtyToBuy + " " + item.unit + "(s) @ $" + item.price 
                                              + " per " + item.unit.toLowerCase());

    if(item.bought){
        holder.main.setBackgroundResource(R.drawable.strikeout);
    }


    return view;
}

class Holder{
    TextView main;
    TextView second;
}

}

Why is this happening? How can i fix this? Any suggestions would be much appreciated.

user11559
  • 28
  • 1
  • 6

2 Answers2

3

The problem is that the convertView gets reused for each item in the list. You're creating a new holder each time, but you're assigning it values referenced from the view.

So what happens is that for one of the entries, you call this and set the background image -

if(item.bought){
    holder.main.setBackgroundResource(R.drawable.strikeout);
}

This isn't just setting the background image for the current list item entry - it's setting a background image on the TextView that's getting reused for each item. And that background image is set in the referenced TextView from that point on - you need to reset it for every use. Something like -

if(item.bought){
    holder.main.setBackgroundResource(R.drawable.strikeout);
} else {
    holder.main.setBackgroundResource(R.drawable.normal);
}
Nate
  • 16,748
  • 5
  • 45
  • 59
0

And the crossed items are saved again and displayed again? Right? Then you should feed the cursor with the new data and call .notifyDataSetChanged() and after the list is populated again (with the new data) call .notifyDatasetInvalidated(); I hope it will work. You do this every time you cross item or show the list.

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
  • On a click I was actually saving the data and changing the individual view rather than giving the adapter the new data and redisplaying the list. I tried what you said, but the problem remains only now it happens when I click on a list item as well. – user11559 Jul 24 '11 at 01:14
  • The position is not correct? If it is the position make this `position = position - listview.getFirstVisibleItem();` – Nikola Despotoski Jul 24 '11 at 01:31