2015-01-21 64 views
0

我可以下載圖像並將其顯示在ListView中。但是我面臨的問題是, 當我加載圖像時,它們都被加載到列表的第一行。它顯示在第一行中逐個加載。而其他行保存默認圖像。它看起來很奇怪。該怎麼辦。下面的代碼:從列表視圖中的URL加載圖像

  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); 
           } 
           } 
          } 
        } 
      } 

這段代碼是類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; 

      } 

的getView功能,如果您有任何疑問,請讓我知道

+0

爲此,您可以使用第三方庫像'Picasso','通用圖像加載程序'和最好的事情是使用'Volley'。 – Piyush 2015-01-21 08:01:42

回答

1

可以使用Picasso加載圖像轉換成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

012 Android上的圖像加載的
@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); 
} 

許多常見的陷阱是由畢加索自動處理:

  1. 處理ImageView回收和下載取消在adapter
  2. 複雜的圖像轉換與最小的內存使用。
  3. 自動內存和磁盤緩存。
+0

感謝您的回覆。我嘗試過畢加索。它沒有消除這個問題。再次,問題是它加載並顯示第一行中的所有圖像,然後將它們顯示在另一個列表中。謝謝 – Popeye 2015-01-21 08:27:34

2

「問題」是ListView的回收行爲。你沒有足夠的尊重。當你向下滾動並且一個View在頂部消失時,它將在底部被重用(這就是爲什麼你使用ViewHolder模式,那很好)。但你也開始一個異步任務,並給它ImageView並保持它。由於該行(以及imageview)的整個視圖被回收,因此它不會有資格進行垃圾回收,因此asynctask有一個有效的ImageView,用於在圖像完成後顯示圖像。

要糾正你的代碼,我建議你就適應什麼是Android開發者頁面上寫的,它幾乎是複製過去就緒代碼供您使用: Load Bitmaps into a GridView Implementation

您也可以使用第三方庫,因爲其他聰明人也面臨着這個問題,並想出好的解決辦法:

  1. Glide
  2. Picasso

它們都有一個非常非常簡單的API來完成任務,它們都非常高效且可以調整,默認情況下已經設置好了。