毕加索:将图像加载到小部件列表视图
Posted
技术标签:
【中文标题】毕加索:将图像加载到小部件列表视图【英文标题】:Picasso: load images to widget listview 【发布时间】:2014-09-06 10:07:03 【问题描述】:我正在根据本教程使用列表视图实现小部件:http://laaptu.wordpress.com/2013/07/24/populate-appwidget-listview-with-remote-datadata-from-web/(源代码:https://github.com/laaptu/appwidget-listview/tree/appwidget-listview2/)。
ListView 项目包含文本和图像,我使用 Picasso 加载图像。
getViewAt 实现:
public RemoteViews getViewAt(int position)
final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.listview_item);
ListItem listItem = listItemList.get(position);
remoteView.setTextViewText(R.id.headline, listItem.headline);
final String imageUrl = listItem.image;
handler.post(new Runnable()
@Override
public void run()
if (!Utils.isEmpty(imageUrl))
picasso.load(imageUrl)
.placeholder(R.drawable.empty_photo)
.into(remoteView, R.id.picture, new int[] appWidgetId );
);
return remoteView;
当图像加载时,它会破坏布局。
可能会出现什么问题?或者我做错了什么?
不加载图片:
图片加载后的样子:
更新:
如果我只添加几个嵌套的远程视图(全部从一个布局膨胀),也会发生同样的情况
更新 2:
报告了一个问题:https://github.com/square/picasso/issues/587
【问题讨论】:
【参考方案1】:在自己解决了这个问题之后,我决定阻止后台线程是可以的(将 .get() 与 Picasso 一起使用)并且能够在我的适配器中得到以下工作:
@Override
public RemoteViews getViewAt(int position)
DBItem item = list.get(position);
RemoteViews view = new RemoteViews(context.getPackageName(), R.layout.widget_item);
try
Bitmap b = Picasso.with(context).load(item.getImageUrl()).get();
view.setImageViewBitmap(R.id.widget_image, b);
catch (IOException e)
e.printStackTrace();
view.setTextViewText(R.id.widget_title, item.getTitle());
return view;
如果您知道返回的图像的大小(如果它始终相同或者您可以预测),您可能还想做这样的事情来减少调整大小的抖动:
@Override
public RemoteViews getLoadingView()
return new RemoteViews(context.getPackageName(), R.layout.v2_widget_item_loading);
性能非常流畅,没有加载抖动,我对结果很满意。
【讨论】:
我应该说我的表现很糟糕。但我 +1 这个答案,因为它只需要一点改进。在调用 .get() 之前调用 .fetch() 以便后续调用同一张图片(当用户上下滚动时)将足够快。 2021,这仍然是最好的解决方案。with(context)
已弃用。用Picasso.get().load(/*URL*/).get()
更改它注意两个得到?两者都不一样。【参考方案2】:
现在已添加此支持,感谢 Square 的好人
我就是这样用的
Picasso.with(mContext)
.load(imagePath)
.into(remoteViews, R.id.some_id, new int[] mAppWidgetId);
享受黄油般流畅的滚动:)
【讨论】:
@ab.helly 是的,你是对的。不幸的是,这在列表视图中不起作用,因为毕加索需要回调主线程。在 listview 远程服务中,您已经在后台线程上。我也解决了这个问题,将缓存的位图存储在地图中并以这种方式提供服务。我最初使用 Picasso 获取它们并调整大小以确保最佳性能。 如何在远程视图工厂中获取 mAppWidgetId,例如。列表视图【参考方案3】:您可以像这样使用 Target Callback 来处理您的问题
Picasso.with(mContext)
.load(imageUrl)
.placeholder(R.drawable.defimage)
.into(new Target()
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from)
mRemoteViews.setImageViewBitmap(R.id.myImage,bitmap);
@Override
public void onBitmapFailed(Drawable errorDrawable)
//do something when loading failed
@Override
public void onPrepareLoad(Drawable placeHolderDrawable)
//do something while loading
);
更多详情请查看article
【讨论】:
那个 Target 会非常快地收集垃圾。 Picasso 对 Targets 的引用很少。只要您希望它存在,您就应该保留对 Target 的引用。以上是关于毕加索:将图像加载到小部件列表视图的主要内容,如果未能解决你的问题,请参考以下文章