Skip to content

Commit

Permalink
Added listener to notify loop completion of a gif (#3438)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnwarShahriar authored and sjudd committed Jan 10, 2019
1 parent c03564a commit a150301
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
1 change: 1 addition & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies {
api project(':third_party:disklrucache')
api project(':annotation')
api "com.android.support:support-fragment:${ANDROID_SUPPORT_VERSION}"
api "com.android.support:animated-vector-drawable:${ANDROID_SUPPORT_VERSION}"
compileOnly "com.android.support:appcompat-v7:${ANDROID_SUPPORT_VERSION}"

if (project.plugins.hasPlugin('net.ltgt.errorprone')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.graphics.drawable.Animatable2Compat;
import android.view.Gravity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.util.Preconditions;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
* An animated {@link android.graphics.drawable.Drawable} that plays the frames of an animated GIF.
*/
public class GifDrawable extends Drawable implements GifFrameLoader.FrameCallback,
Animatable {
Animatable, Animatable2Compat {
/**
* A constant indicating that an animated drawable should loop continuously.
*/
Expand Down Expand Up @@ -76,6 +79,11 @@ public class GifDrawable extends Drawable implements GifFrameLoader.FrameCallbac
private Paint paint;
private Rect destRect;

/**
* Callbacks to notify loop completion of a gif, where the loop count is explicitly specified.
*/
private List<AnimationCallback> animationCallbacks;

/**
* Constructor for GifDrawable.
*
Expand Down Expand Up @@ -351,10 +359,19 @@ public void onFrameReady() {
}

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

private void notifyAnimationEndToListeners() {
if (animationCallbacks != null) {
for (int i = 0, size = animationCallbacks.size(); i < size; i++) {
animationCallbacks.get(i).onAnimationEnd(this);
}
}
}

@Override
public ConstantState getConstantState() {
return state;
Expand Down Expand Up @@ -390,6 +407,42 @@ public void setLoopCount(int loopCount) {
}
}

/**
* Register callback to listen to GifDrawable animation end event after specific loop count
* set by {@link GifDrawable#setLoopCount(int)}.
*
* Note: This will only be called if the Gif stop because it reaches the loop count. Unregister
* this in onLoadCleared to avoid potential memory leak.
* @see GifDrawable#unregisterAnimationCallback(AnimationCallback).
*
* @param animationCallback Animation callback {@link Animatable2Compat.AnimationCallback}.
*/
@Override
public void registerAnimationCallback(@NonNull AnimationCallback animationCallback) {
if (animationCallback == null) {
return;
}
if (animationCallbacks == null) {
animationCallbacks = new ArrayList<>();
}
animationCallbacks.add(animationCallback);
}

@Override
public boolean unregisterAnimationCallback(@NonNull AnimationCallback animationCallback) {
if (animationCallbacks == null || animationCallback == null) {
return false;
}
return animationCallbacks.remove(animationCallback);
}

@Override
public void clearAnimationCallbacks() {
if (animationCallbacks != null) {
animationCallbacks.clear();
}
}

static final class GifState extends ConstantState {
@VisibleForTesting
final GifFrameLoader frameLoader;
Expand Down

0 comments on commit a150301

Please sign in to comment.