我有这个适配器,我加载来自互联网的数据。如果我快速向下滚动,它会在显示正确的图像之前显示错误的图像。但是,图像旁边的相应文本不会这样做。当它下载更多数据时更明显。请帮我调试一下。以下是listview的样子:
使用仅包含textview数据的数据列表初始化categoryAdapter。当调用categoryAdapter的getView()时,它会通过asynctask从url下载图像。当达到列表视图的底部时,OnScrollListener会再下载12篇文章(仅限文本)。这是getView()。请注意,我认为回收旧视图是问题所在,所以我尝试在将imageview的drawable更改为新图像之前将图像快速设置为null,这样我就不会看到旧图像了。如果我快速向上滚动,这是因为没有看到错误,但如果我快速向下滚动则不行。可能是什么问题?
class CategoryAdapter extends BaseAdapter{...
@Override
public View getView(int i, View view, final ViewGroup viewGroup){
// crate a new rowItem object here
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row;
if (view == null) row = inflater.inflate(R.layout.single_row, viewGroup, false);
else row = view;
// Get the description, image and title of the row item
TextView title = (TextView) row.findViewById(R.id.textView);
TextView description = (TextView) row.findViewById(R.id.textView2);
ImageView image = (ImageView) row.findViewById(R.id.imageView);
ProgressBar pb = (ProgressBar) row.findViewById(R.id.progressBarSingleRow);
/* On getting view, set this to invisible until loaded. (issue before: old image seen
before new image on fast scroll) Mostly fixed by this, but on fast scroll down, still
shows a little */
image.setImageDrawable(null);
// Set the values of the rowItem
SingleRow rowTemp = articles.get(i);
title.setText(rowTemp.title);
description.setText(rowTemp.description);
String s = "null";
if (rowTemp.image != null) s = "not null";
Log.e("ImageLog", "Item " + Integer.toString(i) + ", is " + s);
// Load image into row element
if (rowTemp.image == null) { // download
// Prepare prepped row objects in single holder object for fetchCategoryImageTask
AdapterObject holder = new AdapterObject();
holder.title = title;
holder.description = description;
holder.image = image;
holder.pb = pb;
new FetchCategoryImageTask(rowTemp, holder).execute();
}
else { // set saved image
// Cropping image to preserve aspect ratio
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
image.setCropToPadding(true);
image.setImageBitmap(rowTemp.image);
}
return row;
}
以防万一,这里有一点fetchCategoryImageTask()
@Override
protected void onPreExecute() {
image.setVisibility(ImageView.INVISIBLE);
}
@Override
protected Bitmap doInBackground(Void... params) {
return (sr.imageURL != null) ? downloadBitmap(sr.imageURL) : null;
}
@Override
protected void onPostExecute(final Bitmap b) {
// imageView image
// Preserve aspect ratio of image
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
image.setCropToPadding(true);
image.setImageBitmap(b);
// Make image visible
image.setVisibility(ImageView.VISIBLE);
// Save image to SingleRow object for categoryAdapter's getView()
sr.image = b;
}
答案 0 :(得分:2)
这里发生的是ListViews重用视图。因此,它重用已有图像的视图。我建议您使用Volley库或ImageLoader库来解决此问题,在下载图像时很容易定义要显示的占位符。
因此,不要使用Asynctask,而是使用以下代码:
private void showImage(View view, String imageUrl) {
DisplayImageOptions options = new DisplayImageOptions.Builder()//
.showImageOnFail(R.drawable.image_placeholder)
.showImageOnLoading(R.drawable.image_placeholder)
.showImageForEmptyUri(R.drawable.image_placeholder)
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoader.getInstance().displayImage(imageUrl, imageViewType, options);
}
Universal Image Loader库:https://github.com/nostra13/Android-Universal-Image-Loader
答案 1 :(得分:0)
这个答案来自评论,所以我会在这里发布。我每次使用LRU缓存获取行和缓存图像时都不会使用viewHolder模式来查看视图。以下是参考链接:ViewHolder,Caching bitmaps。