7

I'm using fresco to display gifs in a RecyclerView. After the user has tapped an imaged I open a details screen where I should display in the end a high-resolution GIF.

If I just load another GIF in the same DraweeView the content will disappear as this is the way Fresco works and the user will see a black image while the high res one loads, although I already have a low quality preview available.

I also tried using the low-res/high-res scheme, but while the high res image is loading, the low-res is not animated.

Later I discovered the RetainingDataSourceSupplier in Fresco, which works by keeping the current image in a DraweeView until a new one is loaded. This works fine but it doesn't seem to work for animated content.

Can you help me retain the current animated content until the high quality one is downloaded?

Cristian Holdunu
  • 1,880
  • 1
  • 18
  • 43

2 Answers2

3

I ended up rewriting some parts of fresco. Basically, RetainingDataSource was hacking the implementation of the DataSource, keeping it's state in PROGRESS, forever. That means the controllers will never get notified when a new resource is placed into the DataSource and they will never be able to play GIFs.

I managed the problem by modifying the fresco lib code and notified controller after each loaded resource. I've made a PR to fresco, maybe they will agree with the changes as I consider the RetainingDataSource to be incomplete.

You can check the PR here:

Proper support for GIFs when using a RetainingDataSource

Cristian Holdunu
  • 1,880
  • 1
  • 18
  • 43
0

I never used fesco before. But I think this will work.

First load your low-res gif then start a timertask to determine whether the gif is loaded or not using a boolean value.

final boolean gifLoaded = false;
    TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(gifLoaded){
                        timer.cancel();
                        //animate your gif
                    }
                }
            });
        }
    };
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(timerTask,0,200); //check for the gifLoaded value continuously

You can check if the gif is loaded using,

ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
@Override
public void onFinalImageSet(
    String id,
    @Nullable ImageInfo imageInfo,
    @Nullable Animatable anim) {
    if (anim != null) {
      //now the gif is loaded
      gifLoaded = true;
      anim.start();
    }
  }
};

 Uri uri;
 DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setUri(uri)
    .setControllerListener(controllerListener)
     // other setters
    .build();
 mSimpleDraweeView.setController(controller);

I hope this works. For more : Fresco : Animated Images

NirmalCode
  • 2,140
  • 1
  • 14
  • 19
  • this is not the solution. I'm pre-caching the images correctly. The problem relies on the way fresco works. If I set a new controller(which has a new image request) to the DraweeView, it will erase displayed content, show the placeholder, and load the new one. You code basically has the same effect as what I'm using now. – Cristian Holdunu Aug 14 '18 at 07:32
  • can't you use 2 DraweeViews and load the gifs separately. when the highres is loading keep the HighRes DraweeView Gone and after it loaded Make it visible and make the lowres drawee view Gone. – NirmalCode Aug 14 '18 at 07:36
  • I'm using the same component that does the loading for both `RecyclerView` and details screen (which is just a `RecyclerView` itself, but with a details header). I would've like to solve the issue in a proper way, not to hack it. – Cristian Holdunu Aug 14 '18 at 08:00
  • It's exactly what I used. Read my original post :) – Cristian Holdunu Aug 14 '18 at 12:51