【问题标题】:RecyclerView and Picasso images disappear after scrollingRecyclerView 和 Picasso 图像在滚动后消失
【发布时间】:2016-11-05 17:30:09
【问题描述】:

我没有找到答案 here、here 和 here。

我有一个显示帖子列表的活动(有或没有图片)。当我使用SwipeRefreshLayout 向下滚动并向上滚动或刷新列表时,某些图像可能会消失。我使用RecyclerView 显示帖子列表,使用Picasso 加载图像。这是我的适配器绑定:

@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
    // <...>
    if (item.getPhoto() != null) {
        Picasso.with(context)
                .load(item.getPhoto())
                .into(holder.mPostPhoto);
    } else {
        holder.mPostPhoto.setImageDrawable(null);
        holder.mPostPhoto.setVisibility(View.GONE);
    }
}

我发送 HTTP 请求来获取帖子,当我有新数据时,我会调用 PostsAdapter:

public void addAll(List<PostResponse> items) {
    this.items.clear();
    this.items.addAll(items);

    notifyDataSetChanged();
}

在 MainActivity 中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // <...>
    mPostAdapter = new PostAdapter();
    mPosts.setLayoutManager(new LinearLayoutManager(MainActivity.this));
    mPosts.setAdapter(mPostAdapter);

    mPostsSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            updatePosts();
        }
    });

    updatePosts();
}

private void updatePosts() {
    new Api(this).getPosts(new GetPostsCallback(this) {
        @Override
        public void onSuccess(final Paging<PostResponse> paging) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mPostAdapter.addAll(paging.getData());
                    mPostsSwipeRefresh.setRefreshing(false);
                }
            });
        }
    });
}

我觉得这很基本,我不明白为什么图像会一次又一次地消失。我的列表不长,并且在上传到服务器之前调整了图像大小,它们不应该使用太多内存。最糟糕的是,当它们消失时,它们不会重新加载。只有在我向下和向上滚动后,它们才可能重新加载...

  • 请解释一下为什么会这样。
  • 如何解决此问题?

谢谢!

【问题讨论】:

  • 很难说为什么您发布的代码会发生这种情况。你能再分享一点吗?毕加索有什么具体的配置政策吗?
  • @Blackbelt 请查看更新。我没有任何特定的配置。很基础:从服务器获取帖子,每个帖子都有图片url,使用picasso通过url将图片加载到ImageView。
  • 看起来不错 - 如果您登录 item.getPhoto() ?
  • @Blackbelt 我检查了item.getPhoto() 它在那里......

标签: android imageview android-recyclerview android-imageview picasso


【解决方案1】:

我也遇到了这个问题,但不想禁用回收。我发现通过将 ImageView 可见性显式设置为 View.VISIBLE 调用 Picasso,即使在滚动之后也会加载图像:

holder.image.setVisibility(View.VISIBLE);
Picasso.with(context)
    .load(imgUrl)
    .into(holder.image);

【讨论】:

  • 这是正确答案,请采纳,让其他人知道它有效
  • @Billy Brawner,非常感谢你.. 你拯救了我的一天!这应该是正确答案
  • @William 确实工作得很好,但你能解释一下错误的原因吗?
  • @chris 自从我上次看这个已经有几年了,但至少在问题的示例代码中,如果没有任何图像,ImageView 的可见性被设置为View.GONE,但是当将来重用视图时,它永远不会被设置回View.VISIBLE。由于 RecyclerView 只会创建一次视图,然后回收它们(因此得名),即使与视图关联的数据已更改,该可见性状态也会保持
【解决方案2】:

所以,显然RecyclerView 正在从我的列表中回收项目,并且由于某种原因,之后它无法重新加载图像。好问题“为什么?”......也许是因为我做错了什么,不确定。这对我有帮助:

recyclerView.getRecycledViewPool().setMaxRecycledViews(0, 0);

基本上,您正在关闭物品回收。它对我有用,因为我不会渲染大量项目。

【讨论】:

  • 如果你不想回收东西,为什么还要使用回收站视图
  • @HuzefaGadi 我确实想使用 recyclerView。问题是它没有按预期工作..
  • 你救了我的命
  • @Dracarys 很高兴听到这个消息:D
【解决方案3】:

如果您在适配器中使用 if 条件,请尝试以下代码

    if (model.image == null || model.equals(""))
        viewHolder.ivIndieImage.setVisibility(View.GONE);
    else{
        viewHolder.ivIndieImage.setVisibility(View.VISIBLE);
      }

尝试setVisibility对图片可见。

【讨论】:

    【解决方案4】:

    您错过了 onBindViewHolder 中的一件事。在 else 部分中,您将可见性更改为 View.GONE 但在 If 部分中,您不会再次使其可见。因此,在回收器视图中,视图正在被回收意味着数据正在发生变化,但如果您修改任何属性,该视图将保持不变,并且将在使用相同回收视图显示的其他项目中看到。

    【讨论】:

      【解决方案5】:

      我能够通过删除相同的调整大小和中心裁剪方法来解决此问题,但不知何故,它们占用了太多内存并导致图像加载过程混乱

      【讨论】:

        猜你喜欢
        • 2016-08-11
        • 2020-03-13
        • 1970-01-01
        • 2017-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-05
        • 1970-01-01
        相关资源
        最近更新 更多