【问题标题】: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

【问题讨论】:

    标签: android listview android-widget picasso


    【解决方案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 的引用。
    猜你喜欢
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 2014-08-29
    相关资源
    最近更新 更多