Boel
Boel

Reputation: 976

Wrong view delivered by getView in List adapter

I'm displaying a ListView using a BaseAdapter and the ViewHolder pattern.

public class ListViewActivity extends AppCompatActivity {
    private String[] letters = {"A", "B", "C", "D",
            "E", "F", "G", "H", "I", "J", "K", "L",
            "M", "N", "O","P", "Q"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_lv);

        final ListView listView = (ListView) findViewById(R.id.listView);

        listView.setAdapter(new TestBaseAdapter(this, letters));
    }

    class TestBaseAdapter extends BaseAdapter {
        private Context context;
        private String[] values;
        private LayoutInflater inflater;
        public TestBaseAdapter(Context context, String[] values) {
            this.context = context;
            this.values = values;
            this.inflater = LayoutInflater.from(this.context);
        }

        @Override
        public int getCount() {
            return values.length;
        }

        @Override
        public Object getItem(int position) {
            return values[position];

        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            MyViewHolder myViewHolder;

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.lv_layout, parent, false);
                myViewHolder = new MyViewHolder(convertView);
                convertView.setTag(myViewHolder);
            } else {
                myViewHolder = (MyViewHolder) convertView.getTag();
            }

            myViewHolder.title.setText((String)getItem(position));
            if (((String)getItem(position)).equals("A")) {
                myViewHolder.icon.setImageResource(R.drawable.custom_icon);
            }

            return convertView;
        }

        private class MyViewHolder {
            TextView title;
            ImageView icon;

            public MyViewHolder(View item) {
                title = (TextView) item.findViewById(R.id.label);
                icon = (ImageView) item.findViewById(R.id.logo);
            }
        }
    }

}

The code just displays the content of the array in the listview, where every row contains an item from the array, but if the item value is "A", the row show display a different icon. That condition is made in this part of the getView(...) method:

...
if (((String)getItem(position)).equals("A")) {
    myViewHolder.icon.setImageResource(R.drawable.custom_icon);
}
...

When the activity is created, everything seems to be OK:

enter image description here

but when I scroll down the listView, the icon for the A letter is shown randomly over letters different to A.

enter image description here

What am I doing wrong?

Upvotes: 1

Views: 75

Answers (2)

guipivoto
guipivoto

Reputation: 18677

You must update the icon for all views (and not only for those with letter "A").

if (((String)getItem(position)).equals("A")) {
    myViewHolder.icon.setImageResource(R.drawable.custom_icon);
} else {
    myViewHolder.icon.setImageResource(R.drawable.DEFAULT_ICON_ID);
}   

Upvotes: 2

Emerson Dallagnol
Emerson Dallagnol

Reputation: 1269

Android is recycling the views in the list, and the view that you set the icon "A", is passed as argument to method getView, when it isn't visible. The solution is to set the default icon again, like this:

if (((String)getItem(position)).equals("A")) {
    myViewHolder.icon.setImageResource(R.drawable.custom_icon);
} else {
    myViewHolder.icon.setImageResource(/*your default image*/);
}

Upvotes: 4

Related Questions