Question

I have had problems for a long time understanding different aspects of listviews. Here is one issue. I know a workaround but I want to understand why it happens.

Its in the getView-method of a class that extends ArrayAdapter.

I have several listItems and to each I have an image to te left. An for a few listItems, there is an info-image to the right. To this I have added a listener that fires an alertdialog. Let say the app has totally 2 info-images out of 15 listitems.. So far so good. BUT - if I scroll down and then scroll upp - all of the other listitems is now populated with this info-image. Why does this happend, despite using an imageHolder for every view?

public View getView(int position, View convertView, ViewGroup parent) {

    final ViewGroup theParent = parent;
    final int thePosition = position;
    View view = null;
    ViewHolder holder;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.main, parent, false);
        holder = new ViewHolder();
        holder.textView = (TextView) view.findViewById(R.id.label);
        holder.imageView = (ImageView) view.findViewById(R.id.icon);
        holder.infoView = (ImageView) view.findViewById(R.id.imageIcon);
        view.setTag(holder);
    }
    else {
        view = convertView;
        holder = (ViewHolder) view.getTag();
    }

    holder.textView.setText(values[position]);

    switch (thePosition) {
        case 0:
            holder.imageView.setImageResource(R.drawable.conv);
            break;
        case 1:
            holder.imageView.setImageResource(R.drawable.counting);
            break;
        case 2:
            holder.imageView.setImageResource(R.drawable.travelling);
            break;
        case 3:
            holder.imageView.setImageResource(R.drawable.love);
            break;
        case 4:
            holder.imageView.setImageResource(R.drawable.dating);
            holder.infoView.setImageResource(R.drawable.info);
            break;
        case 5:
            holder.imageView.setImageResource(R.drawable.restaurant);
            holder.infoView.setImageResource(R.drawable.info);
            break;
        case 6:
            holder.imageView.setImageResource(R.drawable.thaidishes);
            break;  
        case 7:
            holder.imageView.setImageResource(R.drawable.time_);
            break;
        case 8:
            holder.imageView.setImageResource(R.drawable.time2);
            break;  
        case 9:
            holder.imageView.setImageResource(R.drawable.colours);
            break;
        case 10:
            holder.imageView.setImageResource(R.drawable.weather);
            break;
        case 11:
            holder.imageView.setImageResource(R.drawable.directions);
            break;
        case 12:
            holder.imageView.setImageResource(R.drawable.emergency);
            break;
        case 13:
            holder.imageView.setImageResource(R.drawable.cities);
            break;
    }

    return view;
}

I had a similar problem before with checbox-items. Checked items were unchecked when scrolled out-of view. I solved this by storing checked item as a boolean in an arraylist. Is there a similar solution to this?

The workaround I mentioned is just to set set the imageResourse to zero (0).

Was it helpful?

Solution

The view returned by the getView method gets recycled to minimize resource usage. If one of your views that contains the right info image gets recycled it will still be there.

This works as intended. The solution to this is, as you already discovered, to reset the state of that right info image by using setImageResource(0) or setVisibility(View.GONE) or something similar.

This applies to checkbox state, etc. as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top