Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android : GIF animation cycle complete Listener

I have one GIF image and want to load in Splash Screen. I came across few libraries like android-gif-drawable and Glide

Is there any way I can listen for one animation cycle complete ? I mean once animation cycle is complete(whole animation is completed, without repeating) I want a listener, that Animation is complete, and provides us with some callback. Somewhat like:

SomeLibrary.load("GIF")
.into(imageview)
.repeat(false)
.setOnAnimationCompleteListener(new OnAnimationCompleteListener(){
    public void onAnimationComplete(){
        // Animation is completed. Do whatever you want to do..
    }
});

I have worked with both libraries But looking for a feature as I mentioned above.

like image 536
Chintan Soni Avatar asked Feb 26 '16 06:02

Chintan Soni


4 Answers

For Glide V4 I've found this to be the best answer. https://github.com/bumptech/glide/pull/3438

Glide.with(this).asGif().load(/*your gif url*/).listener(new RequestListener<GifDrawable>() {
    @Override
    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
        return false;
    }

    @Override
    public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
        resource.setLoopCount(1);
        resource.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
            @Override
            public void onAnimationEnd(Drawable drawable) {
                //do whatever after specified number of loops complete
            }
        });
        return false;
    }
}).into(imageView);
like image 172
landnbloc Avatar answered Nov 18 '22 02:11

landnbloc


Update 2018/9/25 After a long period of use in this code

I found that some phones did not really start running in onResourceReady. Means that I get isRunning() == false once onResourceReady is called.

Solution: Sleeping at the beginning.

@Override
    public boolean onResourceReady(final GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
        resource.setLoopCount(1);
        new Thread(new Runnable() {
            @Override
            public void run() {
                Thread.sleep(200);
                while(true) {
                    if(!resource.isRunning()) {
                        onGifFinished();//do your stuff
                        break;
                    }
                }
            }
        }).start();
        return false;
    }

Origin

Because the GIF has a delay when playing, I use the thread to monitor the end of the play. Not a very good but effective way.

Glide.with(this).asGif().load(R.raw.gif)
        .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE)).listener(new RequestListener<GifDrawable>() {
    @Override
    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
        onGifFinished();//do your stuff
        return false;
    }

    @Override
    public boolean onResourceReady(final GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
        resource.setLoopCount(1);
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    if(!resource.isRunning()) {
                        onGifFinished();//do your stuff
                        break;
                    }
                }
            }
        }).start();
        return false;
    }
}).into(iv);
like image 12
Codus Avatar answered Nov 18 '22 02:11

Codus


Below is the complete code for gif 1 loop animation. After completing loop, control will redirects to next activity.

private void initGlideGifImageView() {

    showProgressDialog("Loading image...");
    GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imgSafetyGif, 1);
    Glide
            .with(this)
            .load(GIF_SOURCE_URL)
            .placeholder(R.drawable.img_placeholder_1)
            .error(R.drawable.img_error_1_280_text)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .listener(new RequestListener<String, GlideDrawable>() {

                @Override
                public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                    hideProgressDialog();
                    return false;
                }

                @Override
                public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                    hideProgressDialog();

                    GifDrawable gifDrawable = null;
                    Handler handler = new Handler();
                    if (resource instanceof GifDrawable) {
                        gifDrawable = (GifDrawable) resource;

                        int duration = 0;
                        GifDecoder decoder = gifDrawable.getDecoder();
                        for (int i = 0; i < gifDrawable.getFrameCount(); i++) {
                            duration += decoder.getDelay(i);
                        }

                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
                                startActivity(intent);
                                SplashScreenActivity.this.finish();
                            }
                        }, (duration + 3000));

                    }

                    return false;
                }

            })
            .into(imageViewTarget);
}
like image 2
chinmay.d Avatar answered Nov 18 '22 02:11

chinmay.d


I came a little bit late. I am going to improve the answer of @Codus.

@Override
public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
resource.setLoopCount(1);
resource.registerAnimationCallback(new CustomAnimationCallback() {
       @Override
       public void onEnd(Drawable drawable) {

       }
});
return false;
}

And the CustomAnimationCallback()

public abstract class CustomAnimationCallback extends Animatable2Compat.AnimationCallback {

@Override
public void onAnimationStart(Drawable drawable)
{
    onStart(drawable);
}

@Override
public void onAnimationEnd(Drawable drawable)
{
    onEnd(drawable);
}

public abstract void onStart(Drawable drawable);
public abstract void onEnd(Drawable drawable);
}
like image 2
David Fernández Esteban Avatar answered Nov 18 '22 03:11

David Fernández Esteban