I have a problem with my custom ListView adapter. I want to use ViewHolder (since my listview has 100+ elements), but my listview loops when I use my code. By looping I mean it shows only the initial position and loops their appearance until end of listview. I was suggesting from this site : Click.
This is my code:
public class ListList extends ArrayAdapter<String>{
private final String[] web;
private final Integer[] imageId;
Context context;
public ListList(Context context,
String[] web, Integer[] imageId) {
super(context, R.layout.champion_list, web);
this.context = context;
this.web = web;
this.imageId = imageId;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if(v == null) {
LayoutInflater inflater = LayoutInflater.from(context);
v = inflater.inflate(R.layout.champion_list, null);
holder.txt = (TextView)v.findViewById(R.id.txt);
holder.img = (ImageView)v.findViewById(R.id.img);
holder.txt.setText(web[position]);
holder.img.setImageResource(imageId[position]);
v.setTag(holder);
}
else {
// View recycled !
// no need to inflate
// no need to findViews by id
holder = (ViewHolder) v.getTag();
}
return v;
}
static class ViewHolder {
TextView txt;
ImageView img;
}
}
Any ideas where I did wrong? I tried putting .setText and .setImageResource out from if statement and it works, but according to this site I am doing wrong... Also can you give me any tips how to make listview "lag free"?
Try this :
ViewHolder holder = new ViewHolder();
if(v == null) {
LayoutInflater inflater = LayoutInflater.from(context);
v = inflater.inflate(R.layout.champion_list, null);
holder.txt = (TextView)v.findViewById(R.id.txt);
holder.img = (ImageView)v.findViewById(R.id.img);
v.setTag(holder);
}
else {
holder = (ViewHolder) v.getTag();
}
//move here
holder.txt.setText(web[position]);
holder.img.setImageResource(imageId[position]);
Because you only set the text and image when the adapter loading a first item (the next items will re-use the holder)