Is There A Way To Listen For Animation End In Animatedvectordrawables
Solution 1:
Not tried this yet but Android 6.0 has a registerAnimationCallback method from the Animatable2 interface for this
Edit: yep this works in Android 6.0 emulator:
mAnimatedVectorDrawable.registerAnimationCallback (newAnimatable2.AnimationCallback(){
publicvoidonAnimationEnd(Drawable drawable){
//Do something
}
}
Edit2: looks like they haven't added support for this in the AnimatedVectorDrawableCompat from support lib 23.2+ :(
Edit3: it looks like this got added in support lib 25.3.0
Thanks Carson!
Solution 2:
My first instinct was to take the source code, add some callbacks, and create a custom drawable out of it. Of course, that would have meant no xml support.
It turns out that AnimatedVectorDrawable
uses VectorDrawable's
private method(s). So, this approach won't work.
We could create a simple wrapper class around AnimatedVectorDrawable
and add callbacks:
publicclassAVDWrapper {
private Handler mHandler;
private Animatable mDrawable;
private Callback mCallback;
private Runnable mAnimationDoneRunnable = new Runnable() {
@Override
publicvoidrun() {
if (mCallback != null)
mCallback.onAnimationDone();
}
};
publicinterfaceCallback {
publicvoidonAnimationDone();
publicvoidonAnimationStopped();
}
publicAVDWrapper(Animatable drawable,
Handler handler, Callback callback) {
mDrawable = drawable;
mHandler = handler;
mCallback = callback;
}
// Duration of the animationpublicvoidstart(long duration) {
mDrawable.start();
mHandler.postDelayed(mAnimationDoneRunnable, duration);
}
publicvoidstop() {
mDrawable.stop();
mHandler.removeCallbacks(mAnimationDoneRunnable);
if (mCallback != null)
mCallback.onAnimationStopped();
}
}
Your code would look like:
finalDrawabledrawable= circle.getDrawable();
finalAnimatableanimatable= (Animatable) drawable;
AVDWrapper.Callbackcallback=newAVDWrapper.Callback() {
@OverridepublicvoidonAnimationDone() {
tick.setAlpha(1f);
}
@OverridepublicvoidonAnimationStopped() {
// Okay
}
};
AVDWrapperavdw=newAVDWrapper(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 samefinalDrawabledrawable2= tick.getDrawable();
finalAnimatableanimatable2= (Animatable) drawable2;
animatable2.start();
But, this is exactly what you are doing with setStartDelay
. So I don't know how useful this will be.
Edit: All this can also be implemented inside an extended AnimatedVectorDrawable. But, you'll lose xml support altogether.
Solution 3:
It is strange that there is no direct API for getting this. I suppose a workaround that doesn't involve overrides would just be simply to find the animation in your set of animations that takes the most amount of time, then post a delayed runnable to hide the view.
int longestAnimationTime = 500; //miliseconds, defined in XML possibly?
drawable.start();
drawableView.postDelayed(new Runnable() {
@Override
publicvoidrun() {
drawableView.setVisibility(View.GONE);
}
}, longestAnimationTime);
Downside is that it involves hard coding your longest animation time, but as long as you are referencing the same constant value both in the animation XML and in code, it would work correctly, no overrides needed.
Solution 4:
I found the same problem. I am trying to animate a circle being drawn and a tick inside.
The best I could do is play with durations. Something like this:
finalDrawabledrawable= circle.getDrawable();
finalAnimatableanimatable= (Animatable) drawable;
animatable.start();
tick.setAlpha(0f);
tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();
finalDrawabledrawable2= tick.getDrawable();
finalAnimatableanimatable2= (Animatable) drawable2;
animatable2.start();
It would be great to have a listener
Post a Comment for "Is There A Way To Listen For Animation End In Animatedvectordrawables"