2014-07-21 72 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