Universal-Image-Loader:错误的位图附加到ImageView


问题内容

我一直在评估NOSTRA的Universal-Image-Loader库以异步下载图像并将其显示在ListView中。到目前为止,除了一个问题之外,它都可以正常工作。

有时,ImageViews当列表滚动时,来自内存缓存的位图会附加错误。停止滚动后,将附加正确的图像。这种情况非常罕见,我找不到100%的方式来再现它。我上次拍摄视频时是这样。

这是ArticleAdapter代码,可以在此处bindView()找到UIL配置和方法。

public class ArticleAdapter extends CursorAdapter {
    private LayoutInflater inflater;
    private ViewHolder holder;

    public ArticleAdapter(Context context, Cursor cursor, boolean autoRequery) {
        super(context, cursor, autoRequery);
        imageLoader = ImageLoader.getInstance();
        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.download_progress_thumb)
                .cacheInMemory()
                .cacheOnDisc()
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .build();
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(context)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .threadPoolSize(4)
                .discCache(new UnlimitedDiscCache(Utils.getCacheDirectory(context)))
                .defaultDisplayImageOptions(options)
                .build();
        imageLoader.init(configuration);

        titleIndex = cursor.getColumnIndex(Articles.TITLE);
        descriptionIndex = cursor.getColumnIndex(Articles.DESCRIPTION);
        isUnreadIndex = cursor.getColumnIndex(Articles.IS_UNREAD);
        isNewIndex = cursor.getColumnIndex(Articles.IS_NEW);
        urlIndex = cursor.getColumnIndex(Articles.URL);
        hostIndex = cursor.getColumnIndex(Articles.HOST);
        timeIndex = cursor.getColumnIndex(Articles.PUBLISH_TIME);

        bkgUnreadArticle = context.getResources().getColor(R.color.list_bkg_unread_article);
        bkgReadArticle = context.getResources().getColor(R.color.list_bkg_read_article);
        textUnreadTitle = context.getResources().getColor(R.color.list_text_unread_title);
        textReadTitle = context.getResources().getColor(R.color.list_text_read_title);

        inflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        String date = Utils.format(cursor.getLong(timeIndex), Utils.DATE);
        holder = (ViewHolder) view.getTag();

        holder.titleView.setText(cursor.getString(titleIndex));
        holder.descriptionView.setText(date);

        int isNew = cursor.getInt(isNewIndex);
        if (isNew == 1)
            holder.isNewView.setVisibility(View.VISIBLE);
        else
            holder.isNewView.setVisibility(View.INVISIBLE);

        int isUnread = cursor.getInt(isUnreadIndex);
        if (isUnread == 1){
            holder.titleView.setTextColor(textUnreadTitle);
            holder.rowLayout.setBackgroundColor(bkgUnreadArticle);
        } else {
            holder.titleView.setTextColor(textReadTitle);
            holder.rowLayout.setBackgroundColor(bkgReadArticle);
        }

        String url = cursor.getString(urlIndex);
        String host = cursor.getString(hostIndex);
        if (host.equalsIgnoreCase(Consts.HOST_LENTA) || host.equalsIgnoreCase(Consts.HOST_REALTY)) {
            holder.thumbView.setVisibility(View.VISIBLE);
            imageLoader.displayImage(Utils.makeImageUrl(url, Utils.THUMBNAIL), holder.thumbView);
        } else 
            holder.thumbView.setVisibility(View.GONE);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = inflater.inflate(R.layout.articlelist_item, null);
        ViewHolder holder = new ViewHolder();
        holder.titleView = (TextView) v.findViewById(R.id.list_title);
        holder.descriptionView = (TextView) v.findViewById(R.id.list_description);
        holder.thumbView = (ImageView) v.findViewById(R.id.list_thumb);
        holder.isNewView = (TextView) v.findViewById(R.id.list_read_unread);
        holder.rowLayout = (LinearLayout) v.findViewById(R.id.list_row);

        v.setTag(holder);
        return v;
    }
}

我真的很感谢在此问题上的任何帮助。


问题答案:

对于ListViews,GridViews和其他在其适配器中用于视图重用的列表,
应调用.resetViewBeforeLoading()DisplayImageOptions以防止这种效果。

另外文档说:

只需配置一次即可初始化ImageLoader

你只做一次吗?适配器的构造函数不是它的好地方。

UPD:
对不起,我的回答没有用。.resetViewBeforeLoading()没有帮助,因为您使用.showStubImage(...)。因此,您应该具有正确的UIL工作,但没有。这很奇怪。