Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need Callbacks for when a GifDrawable with an animation finishes it's last loop #1872

Open
mattinger opened this issue Apr 20, 2017 · 10 comments

Comments

@mattinger
Copy link

Glide Version: 3.8.0-SNAPSHOT

Glide load line / GlideModule (if any) / list Adapter code (if any):

glide.load(b).into(new GlideDrawableImageViewTarget(imageView, GlideDrawable.LOOP_INTRINSIC));

I have a series of 3 animated gifs that have to animate themselves in sequence. There seems to be no current way with glide to know when a particular animation is done so that i can start the next one.

GifDrawable seems to be the place where this might have to be

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onFrameReady(int frameIndex) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && getCallback() == null) {
            stop();
            reset();
            return;
        }

        invalidateSelf();

        if (frameIndex == decoder.getFrameCount() - 1) {
            loopCount++;
        }

        if (maxLoopCount != LOOP_FOREVER && loopCount >= maxLoopCount) {
            stop();
        }
    }

i could override that method, however, i'd have no access to the decoder to see if there's any more frames available after the current one.

@TWiStErRob
Copy link
Collaborator

How about overriding stop() and setting the maxLoopCount to 1, so it runs once and then stops. In stop then you can fire the next one.

@TWiStErRob
Copy link
Collaborator

Anyway, if you're up to it a PR would be welcome as well that adds this functionality.

@mattinger
Copy link
Author

I'm not sure stop() is necessarily the right way though. It would trigger even if the animation was manually stopped. I'm looking to trigger the next one only when it runs till completion.

@mattinger
Copy link
Author

So, i've managed to do this, however, what i've seen is that even with the .dontAnimate() flag set, i'm seeing the image being cleared out visually first, and then it animations. This is an issue for me because i'm first loading the initial frame of my images:

Glide.with(imageView.getContext()).load(bytes).asBitmap().into(imageView);

Then i'm animating the first one, and when it stops, the next, and so forth:

glide.load(b).dontAnimate().into(...)

I'm curious if there's a way for me to disable the clearing of the ImageView prior to starting the animation.

@sjudd
Copy link
Collaborator

sjudd commented Apr 24, 2017

Each time you call into() into a View or Target, the previous load is cancelled and the View/Target is cleared.

Your simplest option is probably to use the thumbnail() API to load the first frame.

You could also use a view switcher containing two ImageViews and load the first frame into one view and the GIF into the other.

@mattinger
Copy link
Author

I solved this by setting the existing drawable in the ImageView as the placeholder, and the flicker is now gone. Thanks.

I'll look into a PR for this, but i have to get it approved before i can contribute code (sigh)

@stale
Copy link

stale bot commented Nov 12, 2017

This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions.

@Everlastingsmile
Copy link

Glide 4.7 :
public GifDrawable(Context context, GifDecoder gifDecoder, BitmapPool bitmapPool, Transformation frameTransformation, int targetFrameWidth, int targetFrameHeight, Bitmap firstFrame) {
this(context, gifDecoder, frameTransformation, targetFrameWidth, targetFrameHeight, firstFrame);
}

public GifDrawable(Context context, GifDecoder gifDecoder, Transformation frameTransformation, int targetFrameWidth, int targetFrameHeight, Bitmap firstFrame) {
this(new GifDrawable.GifState(new GifFrameLoader(Glide.get(context), gifDecoder, targetFrameWidth, targetFrameHeight, frameTransformation, firstFrame)));
}

GifDrawable:
In these two Constructor,How to get GifDecoder without reflection ?
Or,Do I have to use reflect if I want a callback for GIF play?

@hadaska
Copy link

hadaska commented Nov 21, 2018

@mattinger @TWiStErRob Can you explain how you did this? I too need a callback for when the gif finishes and I'm trying to extend GifDrawable so I can override the stop() method. However I can't seem to be able to create an instance of my class, that extends GifDrawable, out of the GifDrawable glide returns with the onResourceReady method. Can you explain how you accomplished that?

@chamecall
Copy link

chamecall commented Apr 2, 2020

Glide.with(context) // replace with 'this' if it's in activity
        .load(url)
        .into(new DrawableImageViewTarget(memeBackground) {
            public void onResourceReady(Drawable resource, @Nullable Transition<? super Drawable> transition) {
                if (resource instanceof GifDrawable) {
                    ((GifDrawable) resource).registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
                        @Override
                        public void onAnimationEnd(Drawable drawable) {
                            super.onAnimationEnd(drawable);
                            log.D("animation is completed");
                        }
                    });
                    super.onResourceReady(resource, transition);
                }}});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants