问题描述
我有这个CustomAdapter,以填补我的数据列表。问题是,该ImageView的下载和drawed了很多次。例如:
I have this CustomAdapter, to fill a list with my data. The problem is that the Imageview is downloaded and drawed a lot of times. Example:
我搜到我的服务器的视频列表:
I search to my server a list of videos:
(Video1) Title 1 Description 1
(Video2) Title 2 Description 2
(Video3) Title 3 Description 3
..
在这个负载,从视频1加载的图像,然后在相同的ImageView的Video2Image负载,并再次为列表中的每个视频,同一时代如何影片均榜上有名。当我滚动适配器,这再次下载的所有图像。还有一些选项来解决这个问题,我不明白这behaivour。
When this loads, the image from the Video1 loads, then on the same Imageview, the Video2Image load, and again for each video on the list, same times how videos are on the list. When I scroll the adapter, this download all the images again. There are some option to fix this, I dont understand this behaivour.
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;
}
}
对不起我的英语水平。
Sorry my english.
推荐答案
我回答这个问题之前,我再为您一一解答:不重新发明轮子
I answer that before and I answer it again for you: do not re-invent the wheel!
图像下载/缓存为q pretty复杂的事情对你现在看到的原因(和其他如内存管理,缓存管理等),因此只要使用效果的库。
Image download/caching is q pretty complex thing for reasons you're seeing now (and others such as memory management, cache management, etc), so just use a library that works.
下面是使用code (Android的我最喜爱的图像下载库)
Below is your code using Picasso (my favorite image download library for 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;
}
完成!这code照顾线程,缓存取消。
Done! That code takes care of threading, caching, cancellation.
PS:你应该读多一点regaring适配器和ViewHolder模式,你没有做正确的。
ps.: You should read a bit more regaring adapter and the ViewHolder pattern, you're not doing it correctly.
这篇关于自定义适配器重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!