我有一个Android ListView
,它使用AsyncTask
为每个ListViewItem
下载不同的图片。每个图像在第一次下载时都会添加到ArrayList<Bitmap>
,之后每次都会从ArrayList<Bitmap>
访问。
如果我慢慢滚动ListView
,每个图片都会按预期加载,但如果我开始滚动得更快,那么尚未下载图像的可见ListViewItems
会开始显示项目中的图片已经滚动到屏幕顶部。
最终所有内容都会同步并且图片会通过onPostExecution
来电更新,但出现了什么问题?如何防止以前的项目中的图片出现在ListView
的较低项目中?< / p>
这是修剪过的代码:
private ArrayList<Bitmap> bitmapArray = new ArrayList<Bitmap>(500);
@Override
public View getItemView(final int position, View convertView, final ViewGroup parent) {
View itemView;
if (convertView == null) {
itemView = getInflater().inflate(ITEM_LAYOUT, parent, false);
} else {
itemView = convertView;
}
final ImageView mImageView = (ImageView) itemView.findViewById(R.id.app_component_joblistitemview_logo);
if (bitmapArray.size()>position && bitmapArray.get(position)!=null) {
// Item exists at bitmapArray[position], use it
Log.i("JobListView","Setting Existing for Position:"+position);
mImageView.setImageBitmap(bitmapArray.get(position));
} else {
// Have not downloaded this ListView[position] logo yet
bitmapArray.add(position,null); // add temporary null value until the image is downloaded
mImageView.setImageBitmap(null);
new DownloadImageTask().execute(logo.getLogoUUID(), mImageView, position);
}
return itemView;
}
// This AsyncTask downloads an image / logo from a specified URL and then updates the specified ImageView
private class DownloadImageTask extends AsyncTask<Object, Void, Bitmap> {
ImageView imageView;
Integer listViewPosition;
@Override
protected Bitmap doInBackground(Object... params) {
String urlString = "http://www.myimages.com/something/"+params[0].toString();
this.imageView = (ImageView)params[1];
this.listViewPosition = (Integer)params[2];
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
bitmapArray.set(listViewPosition,myBitmap);
return myBitmap;
} catch (Exception e) {
// Log exception
}
}
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}
答案 0 :(得分:0)
else {
// other methods, then set tag and run task
mImageView.setTag(logo.getLogoUUID());
new DownloadImageTask().execute(logo.getLogoUUID(), mImageView, position);
}
和
int uuid=-1;
protected Bitmap doInBackground(Object... params) {
uuid=params[0];
//other methods
}
protected void onPostExecute(Bitmap result) {
//if tag exists check validity
if(imageView.getTag()==null && imageView.getTag().equals(uuid))
imageView.setImageBitmap(result);
}
假设您有2张照片 - 第一张10像素,第二张FHD。当你的项目需要FHD位图下载器开始下载,obvius。当你仍然滚动并且这个项目被“滚出”时,它会在下面(或上面,取决于滚动方向)出现(作为再循环/转换视图)。然后你设置下载10px位图,这是更快。 10 px设置,但以前asynctask下载fhd图片仍在运行,仍然保持对imageView的引用。因此,当下载fhd时,它将替换此10像素。对于解决方法,您可以设置任何identyfying参数,您的“uuid”可能是完美的
listView和适配器的工作原理您可以阅读here和here - 检查方法convertView
中的getView
是什么,您可以使用ViewHolder模式
PS。我看到你的代码中有一些空指针,因为清理?例如:
View itemView;
final ImageView mImageView = //itemView is just created, findViewById will throw NPE
(ImageView) itemView.findViewById(R.id.app_component_joblistitemview_logo);