Popeye
Popeye

Reputation: 380

Loading Image from URL in List View

I can download image and display it in ListView. But the problem I am facing is, When I am loading the images they all get loaded in the first row of the list. It shows being loaded one by one in the first row. While the other rows hold the default image. Its look weird. What to do. The code below:

            private class simpsync extends AsyncTask<String, Integer , Bitmap>{
                private final WeakReference imageViewReference;
                simpsync(ImageView iv){
                    //imageView=iv;
                    imageViewReference=new WeakReference(iv);

                }
                @Override
                protected Bitmap doInBackground(String... param) {

                    Bitmap bmp=CommonFunctions.overlay(CommonFunctions.loadUrlBitmap(param[0]));
                    return bmp;
                }
                  protected void onPostExecute(Bitmap bitmap) {

                      //imageView.setImageBitmap(result);
                      if (isCancelled()) {
                            bitmap = null;
                        }
                        if (imageViewReference != null) {
                            ImageView imageView = (ImageView) imageViewReference.get();
                            if (imageView != null) {

                                if (bitmap != null) {
                                    imageView.setImageBitmap(bitmap);
                                }
                                }
                            }
                  }
            }

This code is the getView function of class BaseAdapter

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

                View vi = convertView;
                ViewHolder holder;

                if(convertView==null){

                    /****** Inflate tabitem.xml file for each row ( Defined below ) *******/
                    //list_book_detail_entry
                    if(requestType==SearchAndIndex.SEARCH_IN_SEPAERATE)
                    {
                        vi = inflater.inflate(R.layout.list_book_detail_buy, parent, false);
                        //vi = inflater.inflate(R.layout.list_book_detail_buy, null);
                    }
                    else{
                        vi = inflater.inflate(R.layout.list_book_detail_entry, parent, false);
                        //vi = inflater.inflate(R.layout.list_book_detail_entry, parent, false);
                    }


                    /****** View Holder Object to contain tabitem.xml file elements ******/

                    holder = new ViewHolder();

                    holder.bookTitle=(TextView)vi.findViewById(R.id.BookTitle);
                    holder.writer = (TextView) vi.findViewById(R.id.WriterName);
                    holder.imageUrl=(ImageView)vi.findViewById(R.id.ImageUrl);
                    holder.isbn=(TextView)vi.findViewById(R.id.BookISBN);
                    holder.serialNumber=(TextView)vi.findViewById(R.id.BookSerialNumber);
                    holder.availabilityView=(ImageView)vi.findViewById(R.id.AvailabilityView);
                    holder.publisher=(TextView)vi.findViewById(R.id.Publisher);
                    holder.publishingDate=(TextView)vi.findViewById(R.id.PublishingDate);
                    /************  Set holder with LayoutInflater ************/
                    vi.setTag( holder );
                }
                else 
                    holder=(ViewHolder)vi.getTag();

                if(data.size()<=0)
                {
                    holder.bookTitle.setText("--");
                    holder.writer.setText("--");
                    holder.publisher.setText("--");
                    holder.publisher.setText("----+--+--");
                }
                else
                {
                    tempValues=null;
                    tempValues = ( BookDetailsStruct ) data.get( position );
                    holder.writer.setText( tempValues.Writer );
                    holder.publisher.setText(tempValues.Publisher);
                    holder.publishingDate.setText(tempValues.getIssueDetail(0).publishingDate);

                    simpsync sp=new simpsync(holder.imageUrl);
                    if(requestType==SearchAndIndex.SEARCH_IN_SEPAERATE)
                     {
                         if(tempValues.getIssueDetail(0)!=null)
                         {
                             String toAdd;
                             if(tempValues.getIssueDetail(0).serialNumber==-1)
                                 toAdd="";
                             else
                                 toAdd=" [ 巻"+tempValues.getIssueDetail(0).serialNumber+" ]";
                             holder.bookTitle.setText( tempValues.BookName+toAdd);
                             sp.execute(tempValues.getIssueDetail(0).smallImageUrl);
                         }
                     }
                     else{
                         if(tempValues.largetNumberIndex!=-1)
                         {
                             String toAdd;
                             if(tempValues.getIssueDetail(tempValues.largetNumberIndex).serialNumber==-1)
                                 toAdd="";
                             else
                                 toAdd=" ("+tempValues.getIssueCount()+"巻)";
                             holder.bookTitle.setText( tempValues.BookName+toAdd);
                             sp.execute(tempValues.getIssueDetail(tempValues.largetNumberIndex).smallImageUrl);
                         }
                         else{
                             holder.bookTitle.setText( tempValues.BookName);
                             sp.execute(tempValues.getIssueDetail(0).smallImageUrl);
                         }
                     }
                     vi.setOnClickListener(new OnItemClickListener( position ));
                }
                return vi;

            }

if you have any further question, please let me know

Upvotes: 0

Views: 212

Answers (2)

degill
degill

Reputation: 1325

The "problem" is the recycle behavior of ListView. You are not respecting it enough. When you scroll down and a View disappears on the top, it will be reused at the bottom (thats why you use the ViewHolder pattern, thats good). But you also start a asynchronous task and give it the ImageView and to hold onto it. Since the whole view of the row (and with that the imageview) gets recycled, it wont be eligible for garbage collection, thus the asynctask has a valid ImageView to display the image once its finished.

To correct your code, I suggest you simply adapt what is written on the android developer page, it nearly is copy-past-ready code for you to use: Load Bitmaps into a GridView Implementation

You can also use 3rd party libraries, because other smart people have also faced this problem and came up with good solutions:

  1. Glide
  2. Picasso

They both have a very (very) simple Api to get things done and they are both highly efficient and tunable, with already good settings by default.

Upvotes: 2

Murtaza Khursheed Hussain
Murtaza Khursheed Hussain

Reputation: 15336

You can use Picasso for loading images into ListView

@Override 
public void getView(int position, View convertView, ViewGroup parent) {
  SquaredImageView view = (SquaredImageView) convertView;
  if (view == null) {
    view = new SquaredImageView(context);
  }
  String url = getItem(position);

  Picasso.with(context).load(url).into(view);
}

OR

@Override 
public void getView(int position, View convertView, ViewGroup parent) {
  View v = convertView;

  ImageView imgView = v.findViewById(R.id.someImageView);

  String url = getItem(position);

  Picasso.with(context).load(url ).into(imgView);
}

Many common pitfalls of image loading on Android are handled automatically by Picasso:

  1. Handling ImageView recycling and download cancelation in an adapter.
  2. Complex image transformations with minimal memory use.
  3. Automatic memory and disk caching.

Upvotes: 1

Related Questions