即使我保存目标,GridView 有时也不会仅使用 Picasso 更新第一个项目

GridView sometimes doesn't update only first item with Picasso even when I save Targets

我看到了一个类似的未回答的问题,但我不能在那里发表评论和提问,即使在第一次加载时他也一直遇到这个问题:Picasso doesn't load first image of ArrayAdapter

所以问题是:我有一个可以无限滚动 GridView 并下载电影海报的应用程序。当我 return 到屏幕的最开始时 - 它有时不会只更新第一张海报并显示其他图片。

我将 Targets 设置为 ImageView 以保持强引用。我的代码如下:

@Override
public View getView(final int position, View view, ViewGroup parent) {

    final MovieObject movieObject = getItem(position);

    if (view == null) {
        view = LayoutInflater.from(getContext()).inflate(R.layout.movie_item, parent, false);
    }

    final ProgressBar spinner = (ProgressBar) view.findViewById(R.id.movie_item_spinner);
    final ImageView poster = (ImageView) view.findViewById(R.id.movie_poster);

    // Target to show/hide ProgressBar on ImageView
    final Target target = new Target() {

        @Override
        public void onPrepareLoad(Drawable drawable) {
            poster.setBackgroundResource(R.color.white);
            spinner.setVisibility(View.VISIBLE);
        }

        @Override
        public void onBitmapLoaded(Bitmap photo, Picasso.LoadedFrom from) {
            poster.setBackgroundDrawable(new BitmapDrawable(photo));
            spinner.setVisibility(View.GONE);
        }

        @Override
        public void onBitmapFailed(Drawable drawable) {
            poster.setBackgroundResource(R.color.white);
        }
    };

    // Save strong reference to be able to show pictures without sliding the screen
    poster.setTag(target);

    Picasso.with(getContext()).load(movieObject.poster_path).into((Target) poster.getTag());

    // If movie doesn't have an image - uses text instead
    if (movieObject.poster_path.contains("null"))
    {
        TextView imageText = (TextView) view.findViewById(R.id.movie_poster_text);
        imageText.setText(movieObject.title);
    }
    poster.setContentDescription(movieObject.title);

    return view;
}

我该如何解决这个问题?

添加:我还尝试将 Targets 保存在 MovieObject 中,我还尝试为 Target 声明单独的 class - 没有任何帮助。

通过回调解决了问题:

@Override
public View getView(final int position, View view, ViewGroup parent) {

    ...

    spinner.setVisibility(View.VISIBLE);

    Picasso.with(getContext()).load(movieObject.poster_path).into(poster, new Callback() {
        @Override
        public void onSuccess() {
            spinner.setVisibility(View.GONE);
        }

        @Override
        public void onError() {
            poster.setBackgroundResource(R.color.white);
        }
    });

    ...

    return view;
}

我仍然不确定海报将如何回收。

在 Picasso 文档中,他们有以下注释:

注意:Callback 参数是一个强引用,将防止您的 Activity 或 Fragment 被垃圾回收。如果您使用此方法,强烈建议您调用相邻的 Picasso.cancelRequest(android.widget.ImageView) 调用以防止临时泄漏。

我应该在哪里实现它?