我有一个GIF图像,想加载启动画面。 我遇到了一些像android-gif-drawable 和Glide
这样的库有什么方法可以听一个动画周期完成吗? 我的意思是一旦动画循环完成(整个动画完成,不重复)我想要一个监听器,动画完成,并为我们提供一些回调。有点像:
SomeLibrary.load("GIF")
.into(imageview)
.repeat(false)
.setOnAnimationCompleteListener(new OnAnimationCompleteListener(){
public void onAnimationComplete(){
// Animation is completed. Do whatever you want to do..
}
});
我曾与两个图书馆合作但是正在寻找我上面提到的功能。
答案 0 :(得分:10)
更新2018/9/25 在此代码中使用了很长时间后
我发现有些手机并没有真正开始在onResourceReady
中运行。这意味着我会在调用isRunning() == false
后获得onResourceReady
。
解决方案:在开始时睡觉。
@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;
}
<强>来源强>
由于GIF在播放时有延迟,我使用该线程来监控播放的结束。 不是一个非常好但有效的方法。
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);
答案 1 :(得分:2)
以下是gif 1循环动画的完整代码。完成循环后,控件将重定向到下一个活动。
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);
}
答案 2 :(得分:1)
你可以使用这个具有onAnimationCompleted的gif库LINK,它在循环完成时调用它也有get duration方法,它给出一个循环的持续时间,你可以使用任何你想要的
File gifFile = new File(getFilesDir(),"anim.gif");
GifDrawable gifFromFile = new GifDrawable(gifFile);
gifFromFile.addAnimationListener(new AnimationListener() {
@Override
public void onAnimationCompleted(int loopNumber) {
}
});
答案 3 :(得分:1)
我来晚了一点。我将改善@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;
}
和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);
}
答案 4 :(得分:0)
对于Glide V4,我发现这是最好的答案。 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);
答案 5 :(得分:-1)
将Glide库作为模块导入项目并在GifDrawable.java中进行更改
public void setOnAnimationListener(AnimationListener listener) {
this.animationListener = listener;
}
public interface AnimationListener {
void onAnimationStarted();
void onAnimationEnded();
}
//add listener to startRunning and stopRunning methods
private void startRunning() {
if (animationListener != null)
animationListener.onAnimationStarted();
}
private void stopRunning() {
if (animationListener != null)
animationListener.onAnimationEnded();
}
//when loading gifs add request listeners and setAnimationCallback to the GifDrawable
@Override
public void onResourceReady(Drawable resource, @Nullable Transition<?
super Drawable> transition) {
if (resource instanceof GifDrawable) {
GifDrawable gifDrawable = (GifDrawable) resource;
gifDrawable.setOnAnimationListener(new AnimationListener() {
@Override
public void onAnimationStarted() {
Log.d("onAnimation", "Started");
//dothings();
}
@Override
public void onAnimationEnded() {
Log.d("onAnimation", "Stopped");
//dothings();
}
}
});
}
super.onResourceReady(resource, transition);
}