2014-07-21 115 views
0

我有這個CustomAdapter,用我的數據填充一個列表。問題在於Imageview被下載並繪製了很多次。例如:自定義適配器重複

我搜到我的服務器的視頻列表:

(Video1) Title 1 Description 1 

(Video2) Title 2 Description 2 

(Video3) Title 3 Description 3 

.. 

當這種負載,從視頻1加載圖像,然後在相同的ImageView的Video2Image負載,並再次對每個視頻列表,同一時間視頻如何在列表中。當我滾動適配器時,會再次下載所有圖像。有一些選項可以解決這個問題,我不理解這種行爲。

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<Video> { 
    // declaring our ArrayList of items 
    private ArrayList<Video> objects; 

    public CustomAdapter(Context context, int textViewResourceId, ArrayList<Video> objects) { 
     super(context, textViewResourceId, objects); 
     this.objects = objects; 
    } 

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

     View v = convertView; 

     if (v == null) { 
      LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = inflater.inflate(R.layout.list_row, null); 
     } 

     Video i = objects.get(position); 

     if (i != null) { 

      TextView title = (TextView) v.findViewById(R.id.title); 
      TextView description = (TextView) v.findViewById(R.id.description); 
      ImageView imagen = (ImageView) v.findViewById(R.id.list_image); 

      title.setText(i.getTitulo()); 
      description.setText(i.getDescripcion()); 

      //Creamos imagen descargada y la seteamos 
      new DownloadImageTask(imagen).execute(i.getUrlimagen()); 
      BitmapDrawable drawable = (BitmapDrawable) imagen.getDrawable(); 
      Bitmap bitmap = drawable.getBitmap(); 
      imagen.setImageBitmap(bitmap); 

      Log.i("Debug", "Creando una imagen para: " + i.getTitulo()); 

      v.setTag(R.id.id_url, i.getUrl().trim());//1.Url 
      v.setTag(R.id.id_titulo,i.getTitulo().trim());//2.Título 
      v.setTag(R.id.id_video,i.getId().trim());//3.ID 

     } 

     return v; 

    } 

    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(); 
       BitmapFactory BitmapFactory = null; 
       mIcon11 = BitmapFactory.decodeStream(in); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return mIcon11; 
     } 

     protected void onPostExecute(Bitmap result) { 
      if(result!=null) 
       bmImage.setImageBitmap(result); 
     } 
    } 

    public ArrayList getValues(){ 
     return objects; 
    } 

} 

對不起我的英語。

回答

1

我回答之前,我再次回答你:不要重新發明輪子!

由於您現在看到的原因(以及其他內存管理,緩存管理等),圖像下載/緩存是相當複雜的事情,所以只需使用可用的庫。

下面是一個使用Picasso(我最喜愛的圖像下載庫用於Android系統)代碼

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

    View v = convertView; 

    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(R.layout.list_row, null); 
    } 

    Video i = objects.get(position); 

    if (i != null) { 

     TextView title = (TextView) v.findViewById(R.id.title); 
     TextView description = (TextView) v.findViewById(R.id.description); 
     ImageView imagen = (ImageView) v.findViewById(R.id.list_image); 

     title.setText(i.getTitulo()); 
     description.setText(i.getDescripcion()); 

     //Creamos imagen descargada y la seteamos 
     Picasso 
      .with(imagen.getContext()) 
      .load(i.getUrlimagen()) 
      .into(imagen); 

     Log.i("Debug", "Creando una imagen para: " + i.getTitulo()); 

     v.setTag(R.id.id_url, i.getUrl().trim());//1.Url 
     v.setTag(R.id.id_titulo,i.getTitulo().trim());//2.Título 
     v.setTag(R.id.id_video,i.getId().trim());//3.ID 

    } 

    return v; 

} 

完成!該代碼負責線程,緩存和取消。

ps:你應該多讀一點regared適配器和ViewHolder模式,你做得不對。

+0

工程不錯!它是一個非常好的lib,謝謝! – Genaut

0

你的getview總是創建一個DownloadImageTask。你不想這樣做 - 你想檢查一下,看看你是否已經擁有了它,並且只有在你沒有時才下載新的。

1

我以前有過這個問題。如果您在getView()中輸入日誌,則只要滾動到屏幕末尾,就會看到它被調用。這意味着圖片在您滾動時會被多次下載。

要解決這個問題,你需要緩存你的位圖。一旦你有一個緩存,每次你調用getView時,首先對緩存進行一次查詢,以查看該圖像是否已經被下載,如果該圖像不可用,請下載並將其添加到緩存中。

此方法在Android開發人員處進行了解釋(使用代碼)。 http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html