Есть ли способ прослушать конец анимации в AnimatedVectorDrawables

Я создал AnimatedVectorDrawable, он работает очень хорошо, теперь я ищу способ изменить анимацию или скрыть представление после его завершения. Я надеялся, что есть слушатель, но это не похоже на то, что есть. Может кто-нибудь помочь?

РЕДАКТИРОВАТЬ

Поэтому я нашел обходной путь, но не очень элегантный. То, что я сделал, это создать поток и опрос, если анимация запущена.

new Runnable() { public void run() { while(mLoop) { if(mAnimatedVectorDrawable.isRunning()) { Thread.sleep(mPollingInterval); } else { mLoop = false; // TODO what ever } } } }; 

Если кто-то найдет лучшее решение, пожалуйста, поделитесь.

Solutions Collecting From Web of "Есть ли способ прослушать конец анимации в AnimatedVectorDrawables"

Мой первый инстинкт заключался в том, чтобы взять исходный код, добавить некоторые обратные вызовы и создать из него пользовательский доступный. Конечно, это означало бы отсутствие поддержки xml.

Оказывается, что AnimatedVectorDrawable использует частный метод (ы) VectorDrawable's . Таким образом, этот подход не будет работать.

Мы могли бы создать простой класс-оболочку вокруг AnimatedVectorDrawable и добавить обратные вызовы:

 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.

Не пробовал это, но Android 6.0 имеет метод registerAnimationCallback из интерфейса Animatable2 для этого

Изменить: yep это работает в эмуляторе Android 6.0:

 mAnimatedVectorDrawable.registerAnimationCallback (new Animatable2.AnimationCallback(){ public void onAnimationEnd(Drawable drawable){ //Do something } } 

Изменить: похоже, что они не добавили поддержку для этого в AnimatedVectorDrawableCompat из поддержки lib 23.2+ 🙁

Странно, что для этого нет прямого API. Я предполагаю, что обходной путь, который не включает переопределения, просто будет просто найти анимацию в вашем наборе анимаций, которая занимает больше времени, а затем опубликовать задержанную runnable, чтобы скрыть представление.

 int longestAnimationTime = 500; //miliseconds, defined in XML possibly? drawable.start(); drawableView.postDelayed(new Runnable() { @Override public void run() { drawableView.setVisibility(View.GONE); } }, longestAnimationTime); 

Недостатком является то, что он включает в себя жесткое кодирование вашего самого длинного времени анимации, но пока вы ссылаетесь на одно и то же значение константы как в XML-анимации, так и в коде, оно будет работать правильно, без необходимости переопределения.

Я нашел ту же проблему. Я пытаюсь оживить кружок, нарисованный, и галочку внутри.

Лучшее, что я мог сделать, это играть с продолжительностью. Что-то вроде этого:

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

Было бы здорово, если бы слушатель