Search code examples
androidlistviewandroid-listviewandroid-viewholder

Adapter with ViewHolder - loop


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"?


Solution

  • 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)