Reputation: 976
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:
but when I scroll down the listView, the icon for the A letter is shown randomly over letters different to A.
What am I doing wrong?
Upvotes: 1
Views: 75
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
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