【发布时间】:2014-12-09 23:14:56
【问题描述】:
我有一个安卓ListView,它使用AsyncTask 为每个ListViewItem 下载不同的图像。每张图片在第一次下载时都会添加到ArrayList<Bitmap>,之后每次都可以从ArrayList<Bitmap> 访问。
如果我慢慢滚动浏览ListView,每个图像都会按预期加载,但如果我开始更快地滚动,尚未下载其图像的可见ListViewItems 开始显示已经滚动的项目的图像离开屏幕顶部。
最终一切都同步了,图像通过onPostExecution 调用更新,但出了什么问题/如何防止以前项目中的图像出现在ListView 的下部项目中?
这是精简后的代码:
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);
}
}
【问题讨论】:
-
写一个好的/工作的图像加载器并不是一件容易的事......最好使用已经写好的......你将面临的下一个问题是内存管理...... ArrayList
当然将导致OOE Sonner或更晚
标签: android listview android-asynctask android-imageview