Use a thumbnail as a placeholder for Picasso

From a UX point of view, it would be great to show the user the thumbnail first until the real image finishes loading and then shows it to him, but Picasso only uses the resource file as the owner of the place, for example:

Picasso.with(context)
    .load(url)
    .placeholder(R.drawable.user_placeholder)
    .into(imageView);

      

So how can I use the thumbnail url as a placeholder? And if I have to use Picasso twice, then how?

This question is already open on the Picasso github page with this request, but it looks like it won't be added to Picasso according to JakeWharton. So how can we do this with the available ones?

+3


source to share


3 answers


Thanks to raveN here and the comments on the original request on github, I finally have a working solution:

Picasso.with(context)
       .load(thumb) // thumbnail url goes here
       .into(imageView, new Callback() {
            @Override
            public void onSuccess() {
                Picasso.with(context)
                        .load(url) // image url goes here
                        .placeholder(imageView.getDrawable())
                        .into(imageView);
            }
            @Override
            public void onError() {

            }
        });

      

The trick here is to pull from the ImageView (which is a thumbnail) after the first call and pass it as a placeholder to the second call



- update -

I made a post describing the whole scenario

+23


source


You can write a simple helper that calls Picasso twice (as you mentioned).

I haven't tested it, but it should look like

Picasso.with(context)
        .load(thumbnailUrl)
        .error(errorPlaceholderId)
        .into(imageView, new Callback() {
                        @Override
                        public void onSuccess() {
                                // TODO Call Picasso once again here
                        }

                        @Override
                        public void onError() {                             
                    }
            );

      



There are several different ways to summon your Picasso twice. One way I could think of (again, not tested) is

public static void loadImageWithCallback(String url, Callback callback) {
    Picasso.with(context)
        .load(url)
        .error(errorPlaceholderId)
        .into(imageView, callback);
}

public static void loadImage(String url) {
    Picasso.with(context)
        .load(url)
        .error(errorPlaceholderId)
        .into(imageView);
}

loadImageWithCallback("http://example.com/mythumbnail.jpg", new Callback() {

                    @Override
                    public void onSuccess() {
                        loadImage("http://example.com/myRealImage.jpg");    
                    }

                    @Override
                    public void onError() {                             
                }
}

      

Edit: all I know is that Picasso provides this callback mechanism. I am using it in my application to hide the ProgressBar that is displayed before the image is loaded. I'll hide this with success or error callbacks - so you'll be able to get notified when the image is loaded. Then you can just call it again. Hope this approach works.

+3


source


I originally used AbdelHady's solution, but found that the larger image is only loaded after the sketch has been loaded, so I came up with this.

Assuming you have a utility class in your project;

public final class U {

public static void picassoCombo(final RequestCreator thumbnail,
                                final RequestCreator large,
                                final ImageView imageView) {
    Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            imageView.setImageBitmap(bitmap);
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            imageView.setImageDrawable(errorDrawable);
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
            thumbnail.into(imageView);
        }
    };

    imageView.setTag(target); // To prevent target from being garbage collected
    large.into(target);
}
}

      

Application:

U.picassoCombo(
        Picasso.with(context)
                .load("http://lorempixel.com/200/100/sports/1/")
                .placeholder(R.drawable.ic_image_placeholder),
        Picasso.with(context)
                .load("http://lorempixel.com/800/400/sports/1/")
                .error(R.drawable.ic_image_broken),
        imageView
);

      

In the example above, the placeholder is set first, then the thumbnail sketch is set, and whether the thumbnail request is made successful or unsuccessful, the large image request is set upon completion. If the request for a large image fails, then a valid error is set.

The only problem is, if you are using setIndicatorsEnabled(true)

, the debug indicators are not shown for a large query. As far as I can tell it looks by design according to this convo issue

+1


source







All Articles