Fetch images with Callback in Picasso?

I want to show a photo series with no gaps in-between the photos, where photos change in a regular interval. I realized Picasso initializes the ImageView before it starts downloading, and it always does that, no matter if I fetch() or not before calling into().

I fetch() to keep the gap between images small and also use .placeholder(R.color.black), but the gap is still visible, even when the image is loaded from memory.

My code looks like this

Picasso.with(getContext()).load(url).fetch();

then with a delay [which is currently fix and which I want to adjust dependent on network speed]

Picasso.with(getContext()).load(url).into(screenSurface);

I noticed that fetch() does not support any callback parameters and returns void, so it seems it's not possible for me to know when the cache is warmed.

Two questions:

  1. Can I get noticed when an image is cached?
  2. Is there maybe a different way to get rid of the breaks between the images and make them appear regularly.

[I know I could manually code this somehow, but if Picasso supports it, I'd like to use it.]

Based on the source, it looks like fetch does nothing upon completion, including notifying any potential listeners. Unfortunately, FetchAction isn't a public class, so you can't override this functionality either.

You can workaround this problem by using a custom Target subclass, like this:

Picasso.with(getContext()).load(url).into(new Target() {
    @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        // cache is now warmed up
    }
    @Override public void onBitmapFailed(Drawable errorDrawable) { }
    @Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
});

Picasso will load the image just like before, but instead of displaying it in an ImageView, it'll return the Bitmap (or the error!) the Target callback. Let's look at an example. The Picasso creation would be basically the same to our previous examples: Picasso.with(context).load(UsageExampleListViewAdapter.eatFoodyImages).into(target);

I know this is an older question but the fetch() command allows for callbacks such as fetch(Callback callback). This has an onSuccess() and onError() callback for the requested URI load.

See here for javadoc details

Callbacks and Targets In Picasso In Android. Picasso loads the image in two ways synchronously and Asynchronously..fetch() – It will asynchronously load the image into a background thread. This method only saves the image into the disk or memory cache.

The .into() method provides a second argument which is a callback to success and failure. You can use this to keep track of when an image has arrived.

Javadoc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#into-android.widget.ImageView-com.squareup.picasso.Callback-

Have a look at this: How to implement my own disk cache with picasso library - Android? Jake Wharton himself has an answer there.

I have some images that I download from different web sites when the app starts, by doing this: Picasso.with(context).load(image_url).fetch(); Now, suppose the user closes the app and turns offline. When the app starts again, Picasso display the images in this way: Picasso.with(ctx).load(image_url).placeholder(R.drawable.ph).into(imageView);

As of version 2.7 of Picasso, it does support callback with the fetch() method.

Picasso.get()
                    .load(url)
                    .fetch(new Callback() {
                        @Override
                        public void onSuccess() {
                            //Success
                        }
                        @Override
                        public void onError(Exception e) {
                            //Error
                        }});

Displaying images is easiest using a third party library such as Picasso from Square which will download and cache remote images and abstract the complexity behind an easy to use DSL. Before Using Picasso , do not forget to add internet permission in the manifest file . Setup Permission. Adding Internet Permission to our Manifest.xml file:

I tried noPlaceholder method to resolve the problem. I have tried many methods, but eventually found that the question is to make the previous picture wait for next picture.

Loading Images From a URL. We're going to need Picasso to do its job in this section—not to paint us a work of art, but to fetch images from the internet and display them. We'll display these images individually in their respective ImageViews inside our RecyclerView onBindViewHolder() method as the user scrolls the app.

.into(myview, new Callback() {} May be this a problem of weak reference? I don't know why I must implement a new class if in anothers place of my application picasso works perfect.

Fetching image with callback Setting a global error handler for Picasso The reason is, that Picasso doesn’t check if Bitmap converted from Stream is correct. It uses Androids bitmap decoder (BitmapFactory.decodeStream method) which takes the stream and returns Bitmap.

Note: The Callback param is a strong reference and will prevent your Activity or Fragment from being garbage collected. If you use this method, it is strongly recommended you invoke an adjacent Picasso.cancelRequest(android.widget.ImageView) call to prevent temporary leaking.

Comments
  • This is very nice, but I realized I cannot use functions like .fit() or .centerCrop() as I used them before, which is not a problem as I can set the appropriate attributes in the ImageView. But what I would like to know is if using Target() has any implications on caching images. Are the images cached as downloaded so I could technically use them in differently sized previews? Or will I need to .resize() manually or anything the like?
  • You can call load(url).fit().into(screenSurface) after using the workaround in my solution, and as long as url is the same, I believe it will be loaded from the cache.
  • Thanks, I am aware of the Callback in into() and I am using it, but to get a smooth image sequence, I need the information if/when the image is loaded BEFORE into() is called. I will look into implementing my own disk cache, which may solve the problem.