【问题标题】:BaseAdapter and Picasso issueBaseAdapter 和毕加索问题
【发布时间】:2015-04-01 06:35:57
【问题描述】:

我在使用 Picasso 从服务器加载 ListView 中的图像时遇到问题。

我有一个用于填充我的 ListView 的 BaseAdapter。在这个 ListView 中,有些项目有图片,有些没有。

在这个方法中:

public View getView(final int position, View convertView, ViewGroup parent) {

我愿意:

 ...

//context = Activity context;
//context1 = Context context1;
context1 = context.getApplicationContext();

 if (!photo[position].equals("")) {

    String stringurl = "http://www.blablabla.it/img/"+photo[position]+".jpg";

    Picasso.with(context1)
           .load(stringurl)
           .placeholder(R.drawable.white)
           .into(holder.imageD);
        }
 else {

    holder.imageD.setImageBitmap(null);
 }

此代码有效,但我经常看到图像位于与其所属位置不同的位置!

您可以想象这对用户来说非常烦人.. 谢谢大家

【问题讨论】:

  • 您还应该在 else 语句中使用 Picasso 调用...然后应该取消对 holder.imageD 的任何加载请求...
  • @Selvin 所以我应该写: holder.imageD.setImageBitmap(null);如果(...){毕加索...}?可以举个例子吗?
  • else {Picasso.with(context1) .load(null) .placeholder(R.drawable.white) .into(holder.imageD);}
  • @Selvin 写:else{ holder.imageD.setImageBitmap(null); } 不是一回事吗?
  • 不!你看我的评论了吗?

标签: java android listview baseadapter picasso


【解决方案1】:

您遇到过这个问题,因为 ListView 回收项目视图 + Picasso 调用是异步的......它怎么会出现?

  1. 开始用毕加索加载
  2. 视图被重用(convertView != null)
  3. 您正在设置holder.imageD.setImageBitmap(null);
  4. 从第 1 点异步完成。

这就是为什么您加载了错误的图像...

为避免此类行为,您需要通知 Picasso 加载程序取消先前的请求。 因此,只需将图像位图设置为 null,您必须通过 Picasso 库进行设置(在 else 语句中使用):

Picasso.with(context1).load(null).placeholder(R.drawable.white).into(holder.imageD);

编辑:遵循@Budius cmets:更好的解决方案将是取消并设置,例如:

{
  Picasso.with(context1).cancelRequest(holder.imageD);
  //holder.imageD.setImageBitmap(null); //or
  holder.imageD.setImageResource(R.drawable.white); //depends on your needs
}

这应该是更有效的方式,因为它应该在每次 getView 调用时创建更少的内部对象。

【讨论】:

  • 我认为最好手动将图像设置为 null 并通知 Picasso 取消请求 Picasso.with(c).cancelRequest(holder.imageD); holder.imageD.setImageBitmap(null); 您的方式似乎是无缘无故地创建新请求。
  • @Budius ...“新请求”是什么意思? (来自 piccasso 库的请求对象或一些网络请求?)事实上,它与“into”中的代码几乎相同:if (!data.hasImage()) { picasso.cancelRequest(target); target.onPrepareLoad(setPlaceholder ? getPlaceholderDrawable() : null); return; },如果 uri 为 null,则 hasImage 返回 false ...所以不会有网络使用的操作(如果事实上,它将是同步调用)......我的版本也将使用占位符代替空位图
  • 我的意思是库中的 new RequestCreator 对象。从源代码行#293 if (path == null) { return new RequestCreator(this, null, 0); 和行#569 上的private void cancelExistingRequest(Object target) 代码简单地取消现有的。我知道这些很小,但想象一下滚动数千个项目的列表和 GC 必须运行以删除所有这些小对象。关于占位符:也可以在 ImageView 上调用setImageResource(R....)(来源:github.com/square/picasso/blob/master/picasso/src/main/java/com/…
  • 好的 ...我已将您的 cmets 添加到答案中...仍然想知道占位符是否以某种方式缓存...并且 android 框架是否正在缓存 setImageResource ...如果答案是肯定的不,那么第一个版本可能会更有效:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-15
  • 2018-03-10
  • 2014-09-02
相关资源
最近更新 更多