有没有办法在 AnimatedVectorDrawable 中监听动画结束
Is there a way to listen for animation end in AnimatedVectorDrawables
我已经创建了一个 AnimatedVectorDrawable,它工作得很好,现在我正在寻找一种方法来更改动画或在它完成后隐藏视图。我希望有一个听众,但看起来没有。有人可以帮忙吗?
编辑
所以我找到了一个解决方法,但不是一种非常优雅的方法。我所做的是创建一个线程并轮询动画是否为 运行。
new Runnable() {
public void run() {
while(mLoop) {
if(mAnimatedVectorDrawable.isRunning()) {
Thread.sleep(mPollingInterval);
} else {
mLoop = false;
// TODO what ever
}
}
}
};
如果有人找到更好的解决方案,请分享。
我发现了同样的问题。我正在尝试为正在绘制的圆圈和里面的勾号设置动画。
我能做的最好的就是玩持续时间。像这样:
final Drawable drawable = circle.getDrawable();
final Animatable animatable = (Animatable) drawable;
animatable.start();
tick.setAlpha(0f);
tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();
final Drawable drawable2 = tick.getDrawable();
final Animatable animatable2 = (Animatable) drawable2;
animatable2.start();
有一个倾听者就好了
我的第一直觉是获取源代码,添加一些回调,然后从中创建一个自定义可绘制对象。当然,这意味着没有 xml 支持。
事实证明 AnimatedVectorDrawable
使用 VectorDrawable's
私有方法。所以,这个方法行不通。
我们可以围绕 AnimatedVectorDrawable
创建一个简单的包装器 class 并添加回调:
public class AVDWrapper {
private Handler mHandler;
private Animatable mDrawable;
private Callback mCallback;
private Runnable mAnimationDoneRunnable = new Runnable() {
@Override
public void run() {
if (mCallback != null)
mCallback.onAnimationDone();
}
};
public interface Callback {
public void onAnimationDone();
public void onAnimationStopped();
}
public AVDWrapper(Animatable drawable,
Handler handler, Callback callback) {
mDrawable = drawable;
mHandler = handler;
mCallback = callback;
}
// Duration of the animation
public void start(long duration) {
mDrawable.start();
mHandler.postDelayed(mAnimationDoneRunnable, duration);
}
public void stop() {
mDrawable.stop();
mHandler.removeCallbacks(mAnimationDoneRunnable);
if (mCallback != null)
mCallback.onAnimationStopped();
}
}
您的代码如下所示:
final Drawable drawable = circle.getDrawable();
final Animatable animatable = (Animatable) drawable;
AVDWrapper.Callback callback = new AVDWrapper.Callback() {
@Override
public void onAnimationDone() {
tick.setAlpha(1f);
}
@Override
public void onAnimationStopped() {
// Okay
}
};
AVDWrapper avdw = new AVDWrapper(animatable, mHandler, callback);
//animatable.start();
avdw.start(2000L);
tick.setAlpha(0f);
//tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();
// One wrapper is sufficient if the duration is same
final Drawable drawable2 = tick.getDrawable();
final Animatable animatable2 = (Animatable) drawable2;
animatable2.start();
但是,这正是您使用 setStartDelay
所做的。所以我不知道这会有多大用处。
编辑:所有这些也可以在扩展的 AnimatedVectorDrawable 中实现。但是,您将完全失去 xml 支持。
奇怪的是没有直接的API获取这个。我想一个不涉及覆盖的解决方法只是简单地在您的动画集中找到花费最多时间的动画,然后 post 一个延迟的可运行对象来隐藏视图。
int longestAnimationTime = 500; //miliseconds, defined in XML possibly?
drawable.start();
drawableView.postDelayed(new Runnable() {
@Override
public void run() {
drawableView.setVisibility(View.GONE);
}
}, longestAnimationTime);
缺点是它涉及对最长动画时间进行硬编码,但只要您在动画 XML 和代码中引用相同的常量值,它就会正常工作,不需要覆盖。
还没有尝试过,但是 Android 6.0 有一个来自 Animatable2 接口的 registerAnimationCallback 方法
编辑:是的,这适用于 Android 6.0 模拟器:
mAnimatedVectorDrawable.registerAnimationCallback (new Animatable2.AnimationCallback(){
public void onAnimationEnd(Drawable drawable){
//Do something
}
}
Edit2:看起来他们还没有在支持库 23.2+ 的 AnimatedVectorDrawableCompat 中添加对此的支持:(
Edit3:看起来这已添加到支持库 25.3.0
谢谢卡森!
我已经创建了一个 AnimatedVectorDrawable,它工作得很好,现在我正在寻找一种方法来更改动画或在它完成后隐藏视图。我希望有一个听众,但看起来没有。有人可以帮忙吗?
编辑
所以我找到了一个解决方法,但不是一种非常优雅的方法。我所做的是创建一个线程并轮询动画是否为 运行。
new Runnable() {
public void run() {
while(mLoop) {
if(mAnimatedVectorDrawable.isRunning()) {
Thread.sleep(mPollingInterval);
} else {
mLoop = false;
// TODO what ever
}
}
}
};
如果有人找到更好的解决方案,请分享。
我发现了同样的问题。我正在尝试为正在绘制的圆圈和里面的勾号设置动画。
我能做的最好的就是玩持续时间。像这样:
final Drawable drawable = circle.getDrawable();
final Animatable animatable = (Animatable) drawable;
animatable.start();
tick.setAlpha(0f);
tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();
final Drawable drawable2 = tick.getDrawable();
final Animatable animatable2 = (Animatable) drawable2;
animatable2.start();
有一个倾听者就好了
我的第一直觉是获取源代码,添加一些回调,然后从中创建一个自定义可绘制对象。当然,这意味着没有 xml 支持。
事实证明 AnimatedVectorDrawable
使用 VectorDrawable's
私有方法。所以,这个方法行不通。
我们可以围绕 AnimatedVectorDrawable
创建一个简单的包装器 class 并添加回调:
public class AVDWrapper {
private Handler mHandler;
private Animatable mDrawable;
private Callback mCallback;
private Runnable mAnimationDoneRunnable = new Runnable() {
@Override
public void run() {
if (mCallback != null)
mCallback.onAnimationDone();
}
};
public interface Callback {
public void onAnimationDone();
public void onAnimationStopped();
}
public AVDWrapper(Animatable drawable,
Handler handler, Callback callback) {
mDrawable = drawable;
mHandler = handler;
mCallback = callback;
}
// Duration of the animation
public void start(long duration) {
mDrawable.start();
mHandler.postDelayed(mAnimationDoneRunnable, duration);
}
public void stop() {
mDrawable.stop();
mHandler.removeCallbacks(mAnimationDoneRunnable);
if (mCallback != null)
mCallback.onAnimationStopped();
}
}
您的代码如下所示:
final Drawable drawable = circle.getDrawable();
final Animatable animatable = (Animatable) drawable;
AVDWrapper.Callback callback = new AVDWrapper.Callback() {
@Override
public void onAnimationDone() {
tick.setAlpha(1f);
}
@Override
public void onAnimationStopped() {
// Okay
}
};
AVDWrapper avdw = new AVDWrapper(animatable, mHandler, callback);
//animatable.start();
avdw.start(2000L);
tick.setAlpha(0f);
//tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();
// One wrapper is sufficient if the duration is same
final Drawable drawable2 = tick.getDrawable();
final Animatable animatable2 = (Animatable) drawable2;
animatable2.start();
但是,这正是您使用 setStartDelay
所做的。所以我不知道这会有多大用处。
编辑:所有这些也可以在扩展的 AnimatedVectorDrawable 中实现。但是,您将完全失去 xml 支持。
奇怪的是没有直接的API获取这个。我想一个不涉及覆盖的解决方法只是简单地在您的动画集中找到花费最多时间的动画,然后 post 一个延迟的可运行对象来隐藏视图。
int longestAnimationTime = 500; //miliseconds, defined in XML possibly?
drawable.start();
drawableView.postDelayed(new Runnable() {
@Override
public void run() {
drawableView.setVisibility(View.GONE);
}
}, longestAnimationTime);
缺点是它涉及对最长动画时间进行硬编码,但只要您在动画 XML 和代码中引用相同的常量值,它就会正常工作,不需要覆盖。
还没有尝试过,但是 Android 6.0 有一个来自 Animatable2 接口的 registerAnimationCallback 方法
编辑:是的,这适用于 Android 6.0 模拟器:
mAnimatedVectorDrawable.registerAnimationCallback (new Animatable2.AnimationCallback(){
public void onAnimationEnd(Drawable drawable){
//Do something
}
}
Edit2:看起来他们还没有在支持库 23.2+ 的 AnimatedVectorDrawableCompat 中添加对此的支持:(
Edit3:看起来这已添加到支持库 25.3.0
谢谢卡森!