我正在使用数组适配器来填充包含自定义数据的地点列表。文本加载正确,问题在于图像加载。我使用Universal-image-loader异步加载图像。图像被加载但是它们在列表中以错误的顺序放置,并且它们只是在错误的地方一遍又一遍地重新加载。这是我的适配器代码:
public class PlacesListViewAdapter extends ArrayAdapter<PlacesListItem> {
private final Context context;
protected ImageLoader imageLoader = ImageLoader.getInstance();
public PlacesListViewAdapter(Context context, int resourceId, List<PlacesListItem> places) {
super(context, resourceId, places);
this.context = context;
}
private class ViewHolder {
ImageView ivPlaceLogo;
TextView txtPlaceName;
TextView txtPlaceType;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
PlacesListItem placesListItem = getItem(position);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.places_list_item, parent, false);
holder = new ViewHolder();
holder.txtPlaceName = (TextView) convertView.findViewById(R.id.place_name);
holder.txtPlaceType = (TextView) convertView.findViewById(R.id.place_type);
holder.ivPlaceLogo = (ImageView) convertView.findViewById(R.id.place_logo);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtPlaceName.setText(placesListItem.getPlaceName());
holder.txtPlaceType.setText(placesListItem.getPlaceType());
imageLoader.displayImage(placesListItem.getPlaceLogoURL(), holder.ivPlaceLogo);
return convertView;
}
}
答案 0 :(得分:1)
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.placeholder)
.cacheInMemory(true)
.cacheOnDisc(true)
.considerExifParams(true)
.displayer(new RoundedBitmapDisplayer(5))
.build();
答案 1 :(得分:0)
我认为您的问题是由于ImageLoader
异步工作的原因。这里发生的是您将ImageView
实例存储在持有者中,并等待图像加载。但是,如果在加载图像之前重复使用列表项,则会将ImageView
分配给另一个位置 - 而不是您在开始加载时对应的前一个位置。
我不知道在没有持有者的情况下您尝试了哪种确切的实现,但当前的变体并未以任何方式解决异步问题。持有者只是添加了对相同元素(TextView
s,ImageView
s)的另一级引用,当重用列表项时,这些元素将失效。
我建议使用以下简单的实现:
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
PlacesListItem placesListItem = getItem(position);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.places_list_item, parent, false);
}
(TextView)convertView.findViewById(R.id.place_name).setText(placesListItem.getPlaceName());
(TextView)convertView.findViewById(R.id.place_type).setText(placesListItem.getPlaceType());
imageLoader.displayImage(placesListItem.getPlaceLogoURL(), (ImageView)convertView.findViewById(R.id.place_logo));
return convertView;
}
新代码依赖于ImageLoader
提供内部图像缓存的事实。如果它按预期工作,你不需要做任何其他事情。否则,您会注意到每次重复使用列表项时,新图像将替换具有滞后的旧图像(可能是不可接受的延迟)。您应该参考ImageLoader
文档来启用缓存。
免责声明:代码尚未经过测试,我从头脑中写下来。
答案 2 :(得分:0)
我找到了解决方案。列表中的图像错位是由于ImageLoader库处理图像加载的方式。我通过实现ImageLoader缓存并为尚未加载的图像添加占位符来解决问题。