androidlazy-loadingpicassoasync-loading

Implementing "withDelay" in Picasso Android (for skimming)


When dealing with many scrolling images, you have to avoid the problem of loading while skimming, while the user is fast scrolling. The simplest and often best solution is remarkably simple:

just introduce a small delay (say .350) before doing anything.

If the image is already in cache, just load it. Otherwise just wait a bit - and then proceed totally normally.

With the magnificent Picasso, depressingly it looks like there is a fork which in fact does just this, it has a "withDelay" option** (see https://github.com/square/picasso/issues/248)

I'm scared of forks.

But is it possible to do this in Picasso, perhaps using a custom "Target"? So,

My ordinary Picasso call (at the end of a getView...)

Picasso.
  with(State.mainContext).
  load(imageFile.getUrl()).
  placeholder(R.drawable.default).
  noFade().
  into(v.im);

whereas I think I want something like this .......

Picasso.
  with(State.mainContext).
  load(imageFile.getUrl()).
  placeholder(R.drawable.default).
  noFade().
  into(new Target()
     {
     simply wait .350 before proceeding completely normally...
     });

I can't do it, can anyone do it?


Solution

  • edit:

    so apparently the guys at Square just starting to move forward with their stuff. https://github.com/square/picasso/pull/665

    so Lucasr took over and re-organize some of the code. Now the pause/resume can be done in groups, all requests have a DEFAULT_GROUP and apparently the ScrollListener idea was ditched because it's too much of a simple implementation for them to bother, but it's the same code @a.bertucci posted.

    public class SampleScrollListener implements AbsListView.OnScrollListener {
      private final Context context;
      private static final Object scrollTag = new Object(); // this can be static or not, depending what u want to achieve
    
      public SampleScrollListener(Context context) {
        this.context = context;
      }
    
      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        final Picasso picasso = Picasso.with(context);
        if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
          picasso.resumeTag(scrollTag);
        } else {
          picasso.pauseTag(scrollTag);
        }
      }
    
      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                           int totalItemCount) {
        // Do nothing.
      }
    }
    

    this implementation goes with the idea that you'll tag your requests with the context apparently, but just as easily you could tag with default or your custom tags.

    original answer:

    There's already a PullRequest on Picasso for this feature here: https://github.com/square/picasso/pull/561

    It's a bit different from what you suggested, but it works great (I'm using on my app). You have an option to pause/resume dispatching the images to the ImageViews and use an onScrollListener to pause n resume it.

    The code for it is simply:

    listView.setOnScrollListener(new PicassoScrollListener(context));
    

    I agree that forks are annoying because they can get outdated, but can fork it yourself, and keep it up-to-date until it gets merged on Picasso.

    It's not ideal, but the programming is all done for you and it works very well.

    Alternatively you can use my app fork compile 'com.eyeem.picasso:picasso:2.3.3-SNAPSHOT' and keep an eye on that pull request until it gets merged and you revert.