带有 Universal Image Loader 的 ListView 自定义适配器错误地回收图像
ListView custom adapter with Universal Image Loader recycles images wrongly
我已尝试实施建议的回收,如您在下面的代码中所见。原因是 ListView 在滚动和回收视图时滞后是解决它的原因。然而,它也导致了另一个问题,即加载到 ListView 项目中的图像加载不正确。有些视图没有图像,有些则有。在检查没有图像的那些时,UIL 有时会加载不同项目的图片。此外,当我不断上下滚动其他没有图像的项目时,会得到一张属于它们的图像。
这是自定义的 ListViewAdapter:
public class CarListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
String[] name;
String[] owner;
String[] imageUrl;
String[] pricePerKm;
String[] pricePerH;
int amount;
int screenWidth;
ViewHolder viewHolder;
ImageLoader imageLoader;
DisplayImageOptions options;
public CarListViewAdapter(Context context, String[] imageUrl, String[] name, String[] owner,
String[] pricePerKm, String[] pricePerH, int amount, int screenWidth) {
this.context = context;
this.name = name;
this.owner = owner;
this.imageUrl = imageUrl;
this.pricePerKm = pricePerKm;
this.pricePerH = pricePerH;
this.amount = amount;
this.screenWidth = screenWidth;
options = new DisplayImageOptions.Builder()
.cacheOnDisk(true)
.cacheInMemory(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.resetViewBeforeLoading(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.defaultDisplayImageOptions(options)
.threadPriority(Thread.MAX_PRIORITY)
.threadPoolSize(5)
.diskCacheExtraOptions(screenWidth, Math.round(screenWidth / 2), null)
.memoryCache(new WeakMemoryCache())
.denyCacheImageMultipleSizesInMemory()
.build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(config);
}
static class ViewHolder {
ImageView image;
TextView nameText;
TextView ownerText;
TextView pricePerKmText;
TextView pricePerHText;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.car_list, parent, false);
}
viewHolder = new ViewHolder();
viewHolder.image = (ImageView) convertView.findViewById(R.id.car_image);
viewHolder.nameText = (TextView) convertView.findViewById(R.id.car_name);
viewHolder.ownerText = (TextView) convertView.findViewById(R.id.car_owner);
viewHolder.pricePerKmText = (TextView) convertView.findViewById(R.id.car_price_km);
viewHolder.pricePerHText = (TextView) convertView.findViewById(R.id.car_price_h);
viewHolder.image.getLayoutParams().width = screenWidth;
viewHolder.image.getLayoutParams().height = Math.round(screenWidth / 2);
viewHolder.image.requestLayout();
if (imageUrl[position] != null) {
imageLoader.displayImage(imageUrl[position], viewHolder.image);
}
viewHolder.nameText.setText(name[position]);
viewHolder.ownerText.setText(owner[position]);
viewHolder.pricePerKmText.setText(pricePerKm[position]);
viewHolder.pricePerHText.setText(pricePerH[position]);
return convertView;
}
@Override
public int getCount() {
return amount;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
When going over the ones that do not have an image the UIL sometimes
does load a picture of a different item.
这是预期的行为,因为您仅在 imageUrl[position] != null
时才设置项目。尝试为 imageUrl[position]
为空的位置设置一个占位符或隐藏视图。这样你就不会有这种工件。
if (imageUrl[position] != null) {
imageLoader.displayImage(imageUrl[position], viewHolder.image);
} else {
viewHolder.image.setImageResource(R.drawable.place_holder);
}
我已尝试实施建议的回收,如您在下面的代码中所见。原因是 ListView 在滚动和回收视图时滞后是解决它的原因。然而,它也导致了另一个问题,即加载到 ListView 项目中的图像加载不正确。有些视图没有图像,有些则有。在检查没有图像的那些时,UIL 有时会加载不同项目的图片。此外,当我不断上下滚动其他没有图像的项目时,会得到一张属于它们的图像。
这是自定义的 ListViewAdapter:
public class CarListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
String[] name;
String[] owner;
String[] imageUrl;
String[] pricePerKm;
String[] pricePerH;
int amount;
int screenWidth;
ViewHolder viewHolder;
ImageLoader imageLoader;
DisplayImageOptions options;
public CarListViewAdapter(Context context, String[] imageUrl, String[] name, String[] owner,
String[] pricePerKm, String[] pricePerH, int amount, int screenWidth) {
this.context = context;
this.name = name;
this.owner = owner;
this.imageUrl = imageUrl;
this.pricePerKm = pricePerKm;
this.pricePerH = pricePerH;
this.amount = amount;
this.screenWidth = screenWidth;
options = new DisplayImageOptions.Builder()
.cacheOnDisk(true)
.cacheInMemory(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.resetViewBeforeLoading(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.defaultDisplayImageOptions(options)
.threadPriority(Thread.MAX_PRIORITY)
.threadPoolSize(5)
.diskCacheExtraOptions(screenWidth, Math.round(screenWidth / 2), null)
.memoryCache(new WeakMemoryCache())
.denyCacheImageMultipleSizesInMemory()
.build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(config);
}
static class ViewHolder {
ImageView image;
TextView nameText;
TextView ownerText;
TextView pricePerKmText;
TextView pricePerHText;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.car_list, parent, false);
}
viewHolder = new ViewHolder();
viewHolder.image = (ImageView) convertView.findViewById(R.id.car_image);
viewHolder.nameText = (TextView) convertView.findViewById(R.id.car_name);
viewHolder.ownerText = (TextView) convertView.findViewById(R.id.car_owner);
viewHolder.pricePerKmText = (TextView) convertView.findViewById(R.id.car_price_km);
viewHolder.pricePerHText = (TextView) convertView.findViewById(R.id.car_price_h);
viewHolder.image.getLayoutParams().width = screenWidth;
viewHolder.image.getLayoutParams().height = Math.round(screenWidth / 2);
viewHolder.image.requestLayout();
if (imageUrl[position] != null) {
imageLoader.displayImage(imageUrl[position], viewHolder.image);
}
viewHolder.nameText.setText(name[position]);
viewHolder.ownerText.setText(owner[position]);
viewHolder.pricePerKmText.setText(pricePerKm[position]);
viewHolder.pricePerHText.setText(pricePerH[position]);
return convertView;
}
@Override
public int getCount() {
return amount;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
When going over the ones that do not have an image the UIL sometimes does load a picture of a different item.
这是预期的行为,因为您仅在 imageUrl[position] != null
时才设置项目。尝试为 imageUrl[position]
为空的位置设置一个占位符或隐藏视图。这样你就不会有这种工件。
if (imageUrl[position] != null) {
imageLoader.displayImage(imageUrl[position], viewHolder.image);
} else {
viewHolder.image.setImageResource(R.drawable.place_holder);
}