Fresco: Play an animated GIF just once

Created on 24 Jun 2015  ·  21Comments  ·  Source: facebook/fresco

I set the animation to run just ONCE,but it is not useful...what do I do next?

enhancement

Most helpful comment

for workaround..

.setAutoPlayAnimations(false)
.setControllerListener(new BaseControllerListener<ImageInfo>() {
    @Override
    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
        if (animatable != null) {
            try {
              Field field = AnimatedDrawable.class.getDeclaredField("mTotalLoops");
              field.setAccessible(true);
              field.set(animatable, 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
            animatable.start();
        }
    }
})

for fresco v0.10.0+

...
Field field = AbstractAnimatedDrawable.class.getDeclaredField("mTotalLoops");
...

All 21 comments

Did this not work? http://frescolib.org/docs/animations.html#playing-animations-manually

What happened exactly? Is the image a GIF or a WebP?

It is GIF image.It's work,but i want to only make it play once.I use this code in my project:

Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setUri(uri)
    .setAutoPlayAnimations(true)
    .build();
mSimpleDraweeView.setController(controller);

I set the animation to run just once at PS,but in the project the GIF image play repeat..I only want it play once...What do I need to set up?

Please follow the the instructions in the link I posted above.

I'm not sure the documentation answers the question.

Is there a way to have the GIF animate only once, or for some custom BaseControllerListener to understand where in the animation is in its own sequence?

Writing a custom BaseControllerListener allows one to start and stop an animation based on any outside event - but there doesn't seem to be a way for the controller to understand when the animated GIF has already run more than once.

This could be incredibly useful if trying to implement a callback at the end of a given animation.

EDIT: Possibly related to this feature request: https://github.com/facebook/fresco/issues/502

+1

+1

how to play the gif once? i could find the way to do it. please share the way to do it

for workaround..

.setAutoPlayAnimations(false)
.setControllerListener(new BaseControllerListener<ImageInfo>() {
    @Override
    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
        if (animatable != null) {
            try {
              Field field = AnimatedDrawable.class.getDeclaredField("mTotalLoops");
              field.setAccessible(true);
              field.set(animatable, 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
            animatable.start();
        }
    }
})

for fresco v0.10.0+

...
Field field = AbstractAnimatedDrawable.class.getDeclaredField("mTotalLoops");
...

.setAutoPlayAnimations(false)
.setControllerListener(new BaseControllerListener() {
@Override
public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
if (animatable != null) {
try {
Field field = AnimatedDrawable.class.getDeclaredField("mTotalLoops");
field.setAccessible(true);
field.set(animatable, 1);
} catch (Exception e) {
e.printStackTrace();
}
animatable.start();
}
}
})

@m0er it didn't work

@wswenyue try AbstractAnimatedDrawable instead of AnimatedDrawable. There is change class hierarchy a bit.

It worked,Thank you very much @m0er

AbstractAnimatedDrawable可以正常工作播放一次

public void onFinalImageSet(
        String id,
        @Nullable com.facebook.imagepipeline.image.ImageInfo imageInfo,
        @Nullable Animatable anim) {
    if (anim != null) {
        //其他控制逻辑
        AnimatedDrawable an = (AnimatedDrawable) anim;
        ValueAnimator v = an.createValueAnimator();
        v.setRepeatCount(0);
        //其他操作
        v.start();
    }
}

@liyuehui is correct, you can supply value animators to modify the repeat count. Nice trick :)

@oprisnik The method is not working in 1.3.0, it will cause ClassCastException.
com.facebook.imagepipeline.animated.base.AnimatedDrawableSupport cannot be cast to com.facebook.imagepipeline.animated.base.AnimatedDrawable

The problem here is not the version but that you are casting to AnimatedDrawable, which will be AnimatedDrawableSupport on older Android versions. It should work if you cast it to AbstractAnimatedDrawable instead.

@guoxiaoxing

if "animated-base-support" is added
    dependencies {
        compile 'com.facebook.fresco:animated-base-support:x.x.x' 
        //compile(name: 'animated-base-support', ext: 'aar')
    }
        /////////////////////
    public void onFinalImageSet(
            String id,
            @Nullable  imageInfo,
            @Nullable Animatable anim) {
        if (anim != null) {
            // 其他控制逻辑
            com.facebook.imagepipeline.animated.base.AnimatedDrawableSupport an = (com.facebook.imagepipeline.animated.base.AnimatedDrawableSupport) anim;
            com.nineoldandroids.animation.ValueAnimator v = an
                    .createValueAnimator();
            v.setRepeatCount(0);
            v.start();
        }
    }

else "animated-base-support" is not added

    public void onFinalImageSet(
            String id,
            @Nullable  imageInfo,
            @Nullable Animatable anim) {
        if (anim != null) {
            // 其他控制逻辑
            com.facebook.imagepipeline.animated.base.AnimatedDrawable an = (com.facebook.imagepipeline.animated.base.AnimatedDrawable) anim;
            android.animation.ValueAnimator v = an
                    .createValueAnimator();
            v.setRepeatCount(0);
            v.start();
        }
    }



@liyuehui thank you, you save my time.

now for fresco 1.5.0+ ,how to do this?

@liyuehui thank you very much!

Was this page helpful?
0 / 5 - 0 ratings