0

I'm loading a different images to every row in my listview, I've looked at several tutorials and watched the google video on the best practice for this but it still doesn't work properly. My listview items end up displaying all the images in a slideshow and they also change when I scroll my list.

I'm using the Universal Image Loader to download and cache my images. Here is my code for my entire class. I just cant seem to get this to work.

public class EventAdapter extends ArrayAdapter<EventDetails>{

private Context context;
LayoutInflater inflater;
LinkedList<EventDetails> event_details;
ImageView event_imge;
ViewHolder holder;
public ImageLoader imageLoader;


public EventAdapter(Context mcontext,
        LinkedList<EventDetails> m_event_details) {
    super(mcontext, R.layout.event_list_row, m_event_details);

    this.context = mcontext;
    this.event_details = new LinkedList<EventDetails>();
    this.event_details = m_event_details;
}   

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

    View v = myview;

    if (inflater == null) {
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    if (v == null) {
        v = inflater.inflate(R.layout.event_list_row, parent,
                false);
        imageLoader = ImageLoader.getInstance();
        holder = new ViewHolder();
        holder.event_name = (TextView) v.findViewById(R.id.event_name);
        holder.event_show = (TextView) v.findViewById(R.id.event_show);
        holder.event_time = (TextView) v.findViewById(R.id.event_time);
        holder.event_date = (TextView) v.findViewById(R.id.event_date);
        holder.event_genre = (TextView) v.findViewById(R.id.event_genre);
        holder.event_price = (TextView) v.findViewById(R.id.event_price);
        holder.img = (ImageView) v.findViewById(R.id.event_image);
        holder.event_ll = (LinearLayout) v.findViewById(R.id.event_frame_ll);

        v.setTag(holder);
    }else{
        holder = (ViewHolder) v.getTag();
    }

    final EventDetails eD =  event_details.get(position);
    if(eD != null){
        holder.event_name.setText(eD.name.toUpperCase());
        holder.event_show.setText(eD.show.toUpperCase());
        holder.event_time.setText(eD.time.toUpperCase());
        holder.event_date.setText(eD.date.toUpperCase());
        holder.event_price.setText("£"+String.format("%.2f", eD.price));
        holder.event_genre.setText(eD.genre.toUpperCase());

        if(eD.isStandBy == 0){
            holder.event_ll.setVisibility(View.GONE);
        }else{
            holder.event_ll.setVisibility(View.VISIBLE);
        }

        holder.img.setTag(eD.image_url[0]);
        if(MemoryCacheUtil.findCachedBitmapsForImageUri(eD.image_url[0], ImageLoader.getInstance().getMemoryCache()).size() > 0){
            //holder.img.setBackgroundDrawable(new BitmapDrawable(MemoryCacheUtil.findCachedBitmapsForImageUri(eD.image_url[0], ImageLoader.getInstance().getMemoryCache()).get(0)));
            holder.img.setImageBitmap(MemoryCacheUtil.findCachedBitmapsForImageUri(event_details.get(position).image_url[0], ImageLoader.getInstance().getMemoryCache()).get(0));

        }else{              
            DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true).build();
            ImageLoader.getInstance().loadImage(eD.image_url[0], options, new SimpleImageLoadingListener() {                            

                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                    //holder.img.setBackgroundDrawable(new BitmapDrawable(loadedImage));
                    holder.img.setImageBitmap(loadedImage);
                }
            });
        }
    }       

    return v;
}

static class ViewHolder{

    TextView event_name;
    TextView event_show;
    TextView event_time;
    TextView event_date;
    TextView event_genre;
    TextView event_price;
    ImageView img;
    LinearLayout event_ll;
}
Amanni
  • 1,924
  • 6
  • 31
  • 51

1 Answers1

0

Your holder is a class variable. So there is only one instance of holder which gets attached to each of of your recycled views. This should work.

Also, don't use LinkedList to store the items. The access time of LinkedList is O(n). Use ArrayList instead.

public View getView(int position, View myview, ViewGroup parent) {
    ViewHolder holder;

    View v = myview;

    if (inflater == null) {
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    if (v == null) {
        v = inflater.inflate(R.layout.event_list_row, parent,
                false);

        imageLoader = ImageLoader.getInstance();
        holder = new ViewHolder();
        holder.event_name = (TextView) v.findViewById(R.id.event_name);
        holder.event_show = (TextView) v.findViewById(R.id.event_show);
        holder.event_time = (TextView) v.findViewById(R.id.event_time);
        holder.event_date = (TextView) v.findViewById(R.id.event_date);
        holder.event_genre = (TextView) v.findViewById(R.id.event_genre);
        holder.event_price = (TextView) v.findViewById(R.id.event_price);
        holder.img = (ImageView) v.findViewById(R.id.event_image);
        holder.event_ll = (LinearLayout) v.findViewById(R.id.event_frame_ll);

        v.setTag(holder);
    }else{
        holder = (ViewHolder) v.getTag();
    }

    final EventDetails eD =  event_details.get(position);
    if(eD != null){
        holder.event_name.setText(eD.name.toUpperCase());
        holder.event_show.setText(eD.show.toUpperCase());
        holder.event_time.setText(eD.time.toUpperCase());
        holder.event_date.setText(eD.date.toUpperCase());
        holder.event_price.setText("£"+String.format("%.2f", eD.price));
        holder.event_genre.setText(eD.genre.toUpperCase());

        if(eD.isStandBy == 0){
            holder.event_ll.setVisibility(View.GONE);
        }else{
            holder.event_ll.setVisibility(View.VISIBLE);
        }

        holder.img.setTag(eD.image_url[0]);
        if(MemoryCacheUtil.findCachedBitmapsForImageUri(eD.image_url[0], ImageLoader.getInstance().getMemoryCache()).size() > 0){
            //holder.img.setBackgroundDrawable(new BitmapDrawable(MemoryCacheUtil.findCachedBitmapsForImageUri(eD.image_url[0], ImageLoader.getInstance().getMemoryCache()).get(0)));
            holder.img.setImageBitmap(MemoryCacheUtil.findCachedBitmapsForImageUri(event_details.get(position).image_url[0], ImageLoader.getInstance().getMemoryCache()).get(0));

        }else{              
            DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true).build();
            ImageLoader.getInstance().loadImage(eD.image_url[0], options, new SimpleImageLoadingListener() {                            

                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                    //holder.img.setBackgroundDrawable(new BitmapDrawable(loadedImage));
                    holder.img.setImageBitmap(loadedImage);
                }
            });
        }
    }       

    return v;
}
Ganesh Bhambarkar
  • 930
  • 1
  • 8
  • 9
  • This seems to solve the slideshow effect but I still have two images change while scrolling, usually the topmost and bottom visible in the screen. I also had to define the ViewHolder class in getView as final so it could be visible to the holder.img in onDownloadFinished – Amanni Jul 23 '13 at 10:30
  • 1
    It seems the other issue has to do with caching and retrieving my cached images – Amanni Jul 23 '13 at 12:24
  • I looked at this and as long as you don't check for `inflater == null` and just inflate the view then it'll refresh the view like it should. – Brandon Jul 29 '15 at 17:36