0

I use Fresco library to show animated gif files in RecyclerView and android. My code is pretty simple, I do this in onBindViewHolder():

 DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(url)
                .setAutoPlayAnimations(true)
                .build();
 simpleDraweeView.setController(controller);

Everything is fine, but it looks like GIF images are not cached and reloaded when I scroll up or down. So I decided to show preview for GIF files just like simple images. Seems to setLocalThumbnailPreviewsEnabled(true) for ImageRequest doesn't work for GIF images. Then I tried to use ImageDecodeOptionsBuilder with setForceStaticImage(true) - it displays GIFs as static images (almost what I need, but I need to start animation after static image is loaded). Here is the all my code:

    Uri imageUri = Uri.parse(url);
    ImageDecodeOptionsBuilder decodeOptionsBuilder = new ImageDecodeOptionsBuilder();
    decodeOptionsBuilder.setForceStaticImage(true);
    decodeOptionsBuilder.setDecodePreviewFrame(true);
    ImageDecodeOptions imageDecodeOptions = new ImageDecodeOptions(decodeOptionsBuilder);
    ImageRequest request =  ImageRequestBuilder.newBuilderWithSource(imageUri)
            .setImageDecodeOptions(imageDecodeOptions)
            .setLocalThumbnailPreviewsEnabled(true)
            .build();

    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setImageRequest(request)
            .setAutoPlayAnimations(true)
            .build();
    simpleDraweeView.setController(controller);

I also tried to play with setAutoPlayAnimations(true/false) and other parameters (like decodeOptionsBuilder.setDecodePreviewFrame(true)) but still without success.

So my question is: how I can show the static images as preview images (like placeholders) for GIFs? If It's first(or some other) frame from GIF it would be cool. Any help is appreciated.

Evgen
  • 520
  • 4
  • 17

1 Answers1

1

The easiest way to do this is as you described:

Set the GIF where you force the static image. Once you want to play the animation (e.g. on tap), set the image again but this time with setAutoPlayAnimations.

As an alternative, you can also not start the animation automatically but start it on tap, see https://github.com/facebook/fresco/blob/master/samples/animation/src/main/java/com/facebook/samples/animation/MainActivity.java#L131

Basically, you build your controller like this:

DraweeController gifController = Fresco.newDraweeControllerBuilder()
    .setUri(animatedGifUri)
    .setControllerListener(new BaseControllerListener<ImageInfo>() {
      @Override
      public void onFinalImageSet(
          String id,
          ImageInfo imageInfo,
          Animatable anim) {
        if (anim != null) {
          // start the animation with anim.start() whenever you want
        }
      }
    })
    .build();

Unfortunately, there is currently no better way to do this. However, we're looking into improving the animation API for Fresco in the future.

Alexander Oprisnik
  • 1,212
  • 9
  • 9
  • Hi Alexander, thank you for your answer. Basically, I want to use setAutoPlayAnimations(true) and start playing GIF animation automaticaly. For example, It should be like in giphy app (not start it on tap) - https://play.google.com/store/apps/details?id=com.giphy.messenger . Of course, probably they use some other image loader library, but I want to use fresco (I like it more) and implement similar behavior. Regarding fresco, when I scroll up/down I see the placeholders instead of images. I would prefer to see GIFs, but ok, let's assume I want to see just static images (*.jpeg , .png etc). – Evgen Nov 08 '16 at 17:52
  • It's may be some frame from GIF as option. So you mean it's impossible to implement it in this way with fresco for now? Perhaps there is a way somehow change static image in SimpleDraweeView to GIF after static image is loaded (using onFinalImageSet() or something else)? Or use second SimpleDraweeView for GIF at the same place, and make it visible and start animation a bit later (after user has stopped scrolling)? – Evgen Nov 08 '16 at 17:52
  • So for me I just see colored placeholders and then the GIFs for giphy. This could be done with a simple color placeholder drawable. Alternative 1: Just manually start the animation whenever you want to (e.g. when the view has been on screen for some time - see my solution above on how to do that). Alternative 2: set a lowResImageUri with animations off and a normal one with animations on. However, I don't see a benefit with this. – Alexander Oprisnik Nov 08 '16 at 18:40
  • Alternative 1 is not suitable for me because I need to start animation as soon as possible (but instead of colored placeholders I want to see static images). So setAutoPlayAnimations(true) is that what I need. And alternative 2 is impossible(almost) in my case, because I use giphy api for GIFs. And it looks like I cannot get thumbnail *.jpeg or *.png image for GIF through this API. So I need to make thumbmail *.jpeg or *.png image somehow and then show them. Actually, the feature "use first frame(or some other) from GIF as placeholder image for GIF images" will be usefull, I suppose. – Evgen Nov 09 '16 at 10:49
  • Unfortunately, I'm not very familiar with GIFs and fresco source codes to make some improvements or help you with it. And I understand that it's not so easy to implement. I suppose that there will be another issue - where we have to store this static image(or frame) and how to cache it. In any case, thank you for your work and your help, I much appreciate it. I won't mark this issue as resolved, I'm going to back to it later in the future and try to find some acceptable solution for me. – Evgen Nov 09 '16 at 10:49
  • So your main problem is that the GIF decoding is too slow and it takes some time for the GIF to show up? Or what's the reason you want to preview the first frame? I'm part of the Fresco team and I'm working on an improved animation framework that might be more efficient (but it's not ready yet). – Alexander Oprisnik Nov 09 '16 at 19:50
  • The main problem is that user sees placeholders (colored rectangles) for previously loaded GIF files. When we show static images - usually user sees the cached images (if we have them) and sees placeholders only when image hasn't cached yet or has been removed from cache, even when user scrolls up/down. But for GIFs user always sees placeholder images (colored rectangles) when scrolls up/down. As for me it will be enough if user sees just static images as placeholders(but not one placeholder image, different for each image, which related to it. – Evgen Nov 10 '16 at 10:12
  • Like first frame from GIF) instead of colored rectangles. I want to use some frame from GIF, because I don't have other static images for preview GIF. And GIF animation may be started a bit later, but it has to be started (as setAutoPlayAnimations(true) or somehow else). As we can handle scroll events, so probably we can use setForceStaticImage(true) when user scrolls, and say SimpleDraweeView to start animation when scroll idle. Probably it's may be solution, need to check it. – Evgen Nov 10 '16 at 10:13
  • Yeah this is hard to do since the GIF needs to be decoded, which takes some time. Even for images you will see placeholders on older devices since decoding takes a bit of time. If you have a long enough list, there will always be items that show a placeholder due to the memory cache size etc. It would be possible to have a smarter cache that has a higher priority for the preview frame for animations but right now this is not happening. I don't think there is a good solution for this issue. – Alexander Oprisnik Nov 10 '16 at 10:17