2015-02-06 71 views
2

對我來說這是非常大的麻煩,我一直在這工作數小時,並且沒有任何線索!在ListView中加載異步圖像時出現問題

我在ListView中加載異步圖像時出現問題。

我使用Parse.com作爲我的應用程序的後端,我從Parse.com類中檢索消息及其圖像。

一切工作正常,當我向上/向下滾動,或再次加載列表視圖,混合圖片和所有圖片以另一種順序重新加載,幾秒鐘後,他們將按我的意願訂購,但這是一個對我來說是個大問題。

我認爲這正在發生的事情,因爲我使用這樣的類上傳圖片

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> 

反正我的適配器類如下:

public class adapterview extends ArrayAdapter<Message> { 
Bitmap image; 
public adapterview(Context context, ArrayList<Message> Messages) { 
    super(context, 0, Messages); 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // Get the data item for this position 
    final Message m = getItem(position);  
    // Check if an existing view is being reused, otherwise inflate the view 
    if (convertView == null) { 
     convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom2, parent, false); 
    } 

    TextView message = (TextView) convertView.findViewById(R.id.message); 
    TextView date = (TextView) convertView.findViewById(R.id.date); 
    TextView user = (TextView) convertView.findViewById(R.id.user); 
    message.setText(m.getMessage()); 
    user.setText(m.getUser()); 
    new DownloadImageTask((ImageView) convertView.findViewById(R.id.imageView1)) 
    .execute(m.getImage()); 

    return convertView; 


} 


private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 
    ImageView bmImage; 

    public DownloadImageTask(ImageView bmImage) { 
     this.bmImage = bmImage; 
    } 

    protected Bitmap doInBackground(String... urls) { 
     String urldisplay = urls[0]; 
     Bitmap mIcon11 = null; 
     try { 
     InputStream in = new java.net.URL(urldisplay).openStream(); 
     mIcon11 = BitmapFactory.decodeStream(in); 
     } catch (Exception e) { 
      Log.e("Error", e.getMessage()); 
      e.printStackTrace(); 
     } 
     return mIcon11; 
    } 

    protected void onPostExecute(Bitmap result) { 
     bmImage.setImageBitmap(result); 
    } 
} 

,這是我的消息類:

public class Message { 

String message; 
String user; 
String phone; 
String image; 
String date; 

public String getDate() { 
    return date; 
} 

public void setDate(String date) { 
    this.date = date; 
} 

public String getImage() { 
    return image; 
} 

public void setImage(String image) { 
    this.image = image; 
} 

public String getPhone() { 
    return phone; 
} 

public void setPhone(String phone) { 
    this.phone = phone; 
} 

public String getUser() { 
    return user; 
} 

public void setUser(String user) { 
    this.user = user; 
} 

public String getMessage() { 
    return message; 
} 

public void setMessage(String message) { 
    this.message = message; 
} 
} 

以及如何將項目添加到我的列表中:

contacts c = new contacts(); 
      c.setName(object.get("name").toString()); 
      c.setNumero(object.get("phone").toString()); 
      ParseFile image = (ParseFile)object.get("Profil"); 
      c.setProfil(image.getUrl()); 
      messagelist.addcontact(c); 

,這是如何我從填充在MainActivity列表視圖代碼:

 adapterview adapter = new adapterview(MainActivity.this, (ArrayList<Message>) messagelist); 
    list.setAdapter(adapter); 

下面是兩張截圖,當我向下滾動,然後向上第一的listItem變化,使畫面! !無緣無故,然後幾秒鐘後回到正常的圖片。

enter image description here

enter image description here

如果你可以建議我如何可以從網址上傳圖像到ImageView的一種新的方式,那將是巨大的。

回答

2

你所觀察到的,我認爲由於listview.You的viewholder模式通過getview()中的aysnctask下載圖像並將其設置爲圖像,但是當您滾動或縮小視圖時會回收利用,並且當您再次轉到該位置時,getview將調用該位置,以便再次執行asynctask,並下載設置圖像在imageview再次因此你看到延遲,我建議你使用PICASSO libraray從廣場它是圖像下載相當有效率,並在這裏緩存您的圖片是鏈接http://square.github.io/picasso/或使用滑翔這是現在正式由谷歌推薦,這裏是GitHub的鏈接Glide

+0

謝謝,這解決了我的問題:) – 2015-02-06 12:38:23

+0

@NadadorBase基地樂於幫助 – 2015-02-06 15:42:31

1

我上次還使用手動下載聯繫人的頭像,但這很糟糕。 你的問題,我認爲:

  • 下載頭像,然後設置ImageView的
  • 但是,你正在使用ViewHolder模式,所以新下載的頭像將設置很多的ImageView>錯誤化身爲指定聯繫人(這僅運行良好當所有的化身下載)

首先,檢查通用圖像裝載機庫,設置頭像URL到視圖,它會自動下載,緩存你的頭像到內存中。

然後在這裏發帖,如果你仍然得到錯誤的頭像問題。

+0

你可以請給我更多的細節,我該怎麼做你說的?你可以給一個教程,和任何來源 – 2015-02-06 04:00:53

0

什麼是listview單元佈局xml文件? 我認爲Android無法確定listview的單元大小。這會導致一些問題。 如果你想使用異步加載圖像,解決問題的一種方法是修復圖像大小。例如

<ImageView 
     android:id="@+id/row_icon1" 
     android:layout_width="60dip" 
     android:layout_height="60dip" 
     android:layout_gravity="center_vertical" 
    /> 
+0

我已經這樣做了,這是工作良好 – 2015-02-06 03:59:25

1

的照片混合,而所有的照片在另一個順序刷新,並 幾秒鐘後,他們將責令我想

這種怪異的行爲在getView方法發生因AsyncTask沒有查看持有人模式

爲避免再次渲染已渲染的縮略圖圖像並在滾動的列表視圖中從網絡加載新圖像,請使用視圖持有者模式。

參見以下有用的教程使用View持有人具有良好的滾動和加載服務表現創造的ListView:試圖

Performance Tips for Android’s ListView

1

這是因爲ListView的回收滾動視圖時,然後當您調用異步任務下載圖片並滾動時,下載完成但參考指向循環視圖以及指向同一視圖的一個或多個異步任務。有一種方法可以避免這種情況,即在下載開始時以及下載結束時,在繪製圖像之前檢查其標記是否正確,然後繪製圖像。

您可以使用圖像的URL標記視圖,因爲它具有唯一的值。

在下載的預執行中,您必須使用URL(字符串)標記ImageView。

imageView.setTag(url); 

而且當任務完成之前和繪製圖像之前,恢復標記並檢查它。

String tag = (String)imageView.getTag(); 
if(tag != null && tag.equals(url)){ 
    //Draw the image 
} else { 
    //Draw the placeholder or clean the ImageView 
} 

而且你可以升級你的ListView使用ViewHolder模式,以及爲什麼你手動下載圖像時解析可以通過其API執行它,在解析的方式,並使用高速緩存策略的表現,當你下載一個圖像會自動緩存位圖,並且當您再次詢問下載時,只需檢索緩存的結果。

乾杯!

1

我解決了通過使用循環視圖的onBindViewHolder

@Override 
public void onBindViewHolder(final MyViewHolder viewHolder, int i) { 
    CartsViewModel currentData = data.get(i); 
    ParseFile image = currentData.getParseImage(); 
    if(image!=null){ 
     Log.d(TAG,"image not null. Downloading...."); 
     image.getDataInBackground(new GetDataCallback() { 
      @Override 
      public void done(byte[] bytes, ParseException e) { 
       if(e==null){ 
        Log.d(TAG,"donload finished"); 
        Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
        viewHolder.cartImage.setImageBitmap(bmp); 
       }else{ 
        viewHolder.cartImage.setImageBitmap(null); 
       } 
      }else{ 
       viewHolder.cartImage.setImageBitmap(null); 
      } 
     }); 
    } 
    viewHolder.cartName.setText(currentData.getCartName()); 
    viewHolder.cartAddress.setText(currentData.getCartAddress()); 
    viewHolder.rating.setText(currentData.getRating()); 
    viewHolder.reviewCount.setText(currentData.getReviewCount()); 

} 

作品就像用解析方法的魅力。

+0

我解決了調用'viewHolder.cartImage.setImageBitmap( null);'在加載之前 – jose920405 2016-12-01 02:24:55