Android ArrayAdapter加载列表使用universal-image-load库查看图像

时间:2013-12-25 17:14:40

标签: android listview android-arrayadapter

我正在使用数组适配器来填充包含自定义数据的地点列表。文本加载正确,问题在于图像加载。我使用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;    
    }
}

3 个答案:

答案 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缓存并为尚未加载的图像添加占位符来解决问题。