bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.67k stars 6.12k forks source link

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

Open mattinger opened 7 years ago

mattinger commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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

mattinger commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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[bot] commented 7 years ago

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 commented 6 years ago

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 commented 5 years ago

@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 commented 4 years ago
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);
                }}});