Is there a way to listen for animation end in AnimatedVectorDrawables

前端 未结 4 878
一向
一向 2020-12-31 00:35

I have created an AnimatedVectorDrawable, it works pretty well, now I am looking for a way to change the animation or hide the view after it finishes. I was hoping there was

4条回答
  •  清酒与你
    2020-12-31 01:33

    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:

    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();
        }
    }
    

    Your code would look like:

    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();
    

    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.

提交回复
热议问题