毕加索加载到错误的ImageView使用视图持有人模式时,毕加索、持有人、视图、加载

2023-09-05 06:37:21 作者:繁花黎落、诉不尽哀思惆怅

我试图用毕加索库加载外部图像转换成排的的ListView 。我有一个自定义的 ArrayAdapter 如下:

I'm trying to use the Picasso library to load external images into rows in a ListView. I have a custom ArrayAdapter as follows:

public class RevisedBusinessesAdapter extends ArrayAdapter<HashMap<String, String>> {

    Context context;
    int layoutResourceId;
    ArrayList<HashMap<String, String>> data = null;

    public RevisedBusinessesAdapter(Context context, int layoutResourceId,  ArrayList<HashMap<String, String>> data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        RevisedBusinessHolder holder = null;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new RevisedBusinessHolder();
            holder.ivLogo = (ImageView) row.findViewById(R.id.ivBusinessLogo);
            row.setTag(holder);
        } else {
            holder = (RevisedBusinessHolder) row.getTag();
        }

        HashMap<String, String> business = data.get(position);

        String strLogoURL = business.get("logoURL");
        if (null != strLogoURL && !"".equals(strLogoURL)) {
            Picasso.with(this.context).load(strLogoURL).into(holder.ivLogo);        
        }

        return row;
    }

    static class RevisedBusinessHolder {
        ImageView ivLogo;
    }
}

其中logoURL为位于远处的图像的URL;如果不提供, ivBusinessLogo 有一个局部的src集,并显示代替。当我快速滚动,毕加索将图像加载到了错误的的ImageView 和我结束了它在列表中的多个副本。

where logoURL is an URL for a remotely located image; if not supplied, ivBusinessLogo has a local src set, and that is shown instead. When I scroll quickly, Picasso loads the image into the wrong ImageView and I end up with multiple copies of it in the list.

这个问题的答案this问题建议加入

The answer to this question suggests adding

Picasso.with(context).cancelRequest(holder.ivLogo);

在现有毕加索调用之前,但是这并没有什么区别。如果我删除行== NULL 检查并总是创建一个新的观点,它似乎很好地工作。在完整版中这一点,虽然,还有四个textviews等五个图像,需要在每一个 getView 。

before the existing Picasso call, but that doesn't make any difference. If I remove the row == null check and always create a new view, it appears to work fine. In the full version of this, though, there are also four textviews and five other images (small icons loaded from local resources, not via Picasso) that need to be updated in each getView.

有没有一种方法,使这项工作与视图持有人格局 Android的文件建议?

Is there a way to make this work with the View Holder pattern the Android documentation recommends?

推荐答案

您应该总是叫毕加索,即使你的网址是。这样它知道图像视图被回收

You should always call Picasso, even if your URL is null. This way it knows that the image view was recycled.

删除此如果语句:

if (null != strLogoURL && !"".equals(strLogoURL)) {

您也应该考虑使用一个占位符图像或错误图像,当没有URL的东西会被显示出来。

You should also consider using a placeholder image or an error image so that something will be displayed when there is no URL.

如果你坚持要保持如果语句(但你不应该!),你需要告诉毕加索的图像视图被回收,通过调用 cancelRequest

If you insist on keeping the if statement (but you shouldn't!), you need to tell Picasso that the image view was recycled by calling cancelRequest:

Picasso.with(this.context).cancelRequest(holder.ivLogo);