Android: AnimatedVectorDrawable Loop

11,902

Solution 1

You should use AnimatedVectorDrawableCompat instead of AnimatedVectorDrawable to support lower APIs then you can also write that callback and start animation when it ends. Finally your code should be like this:

val animated = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_dice)
    animated?.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
        override fun onAnimationEnd(drawable: Drawable?) {
            animationView.post { animated.start() }
        }

    })
    animationView.setImageDrawable(animated)
    animated?.start()

Solution 2

You can use Animatable2.AnimationCallback and start the AnimatedVectorDrawable animation again in onAnimationEnd

drawable.registerAnimationCallback(new Animatable2.AnimationCallback() {
    @Override
    public void onAnimationEnd(Drawable drawable) {
        avd.start();
    }
});

drawable.start();

Solution 3

use property in your objectAnimator

android:repeatMode="restart"
    android:repeatCount="infinite"

your object is like that

 <objectAnimator
    android:propertyName="pathData"
    android:duration="1000"
    android:valueFrom="path value"
    android:valueTo="some value"
    android:valueType="pathType"
    android:repeatMode="restart"
    android:repeatCount="infinite"
    android:interpolator="@android:anim/overshoot_interpolator"/>

Solution 4

Using @Feryal Sharifzadeh great answer as a base, here's a Kotlin ext function for setting and looping a AVD.

internal fun ImageView.applyLoopingAnimatedVectorDrawable(@DrawableRes avdResId: Int) {
    val animated = AnimatedVectorDrawableCompat.create(context, avdResId)
    animated?.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
        override fun onAnimationEnd(drawable: Drawable?) {
            [email protected] { animated.start() }
        }
    })
    this.setImageDrawable(animated)
    animated?.start()
}
Share:
11,902
Admin
Author by

Admin

Updated on August 21, 2022

Comments

  • Admin
    Admin over 1 year

    I'm playing around with AnimatedVectorDrawables using https://shapeshifter.design/ The exported file I got is below. My research Tells me that in order to loop an animations i should add android:repeatCount="infinite" and android:repeatMode="restart" to the objectAnimator.

    Adding this to the objectAnimator only repeats one of these items out of series. How would I loop the entire series of animations? I want the animation to start on load and repeat.

    Animation XML

    <animated-vector
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:aapt="http://schemas.android.com/aapt">
        <aapt:attr name="android:drawable">
            <vector
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:width="50dp"
                android:height="50dp"
                android:viewportWidth="50"
                android:viewportHeight="50">
                <path
                    android:name="_x34_"
                    android:pathData="M 25 12.3 L 39.7 37.7 L 10.3 37.7 Z"
                    android:fillColor="#ffffff"
                    android:strokeColor="#000000"
                    android:strokeWidth="1"
                    android:strokeLineCap="round"
                    android:strokeLineJoin="round"
                    android:strokeMiterLimit="10"/>
            </vector>
        </aapt:attr>
        <target android:name="_x34_">
            <aapt:attr name="android:animation">
                <set xmlns:android="http://schemas.android.com/apk/res/android">
                    <objectAnimator
                        android:propertyName="pathData"
                        android:duration="1000"
                        android:valueFrom="M 25 12.3 L 39.7 37.7 L 10.3 37.7 L 17.397 25.437 Z"
                        android:valueTo="M 10 10 L 40 10 L 40 40 L 10 40 Z"
                        android:valueType="pathType"
                        android:interpolator="@android:anim/overshoot_interpolator"/>
                    <objectAnimator
                        android:propertyName="pathData"
                        android:startOffset="1000"
                        android:duration="1000"
                        android:valueFrom="M 40 10 L 25.581 10 L 10 10 L 10 40 L 25.349 40 L 40 40 L 40 10"
                        android:valueTo="M 36.3 18.7 L 25 10.4 L 13.7 18.7 L 12.8 31.5 L 25 39.6 L 37.2 31.5 L 36.3 18.7"
                        android:valueType="pathType"
                        android:interpolator="@android:interpolator/fast_out_slow_in"/>
                    <objectAnimator
                        android:propertyName="pathData"
                        android:startOffset="2000"
                        android:duration="1000"
                        android:valueFrom="M 36.3 18.7 L 25 10.4 L 13.7 18.7 L 12.8 31.5 L 25 39.6 L 37.2 31.5 Z"
                        android:valueTo="M 25 10.2 L 12.2 17.6 L 12.2 32.4 L 25 39.8 L 37.8 32.4 L 37.8 17.6 Z"
                        android:valueType="pathType"
                        android:interpolator="@android:anim/overshoot_interpolator"/>
                    <objectAnimator
                        android:propertyName="pathData"
                        android:startOffset="3000"
                        android:duration="1000"
                        android:valueFrom="M 31.365 13.88 L 25 10.2 L 18.268 14.092 L 12.2 17.6 L 12.2 25.465 L 12.2 32.4 L 25 39.8 L 37.8 32.4 L 37.8 25.581 L 37.8 17.6 L 31.365 13.88"
                        android:valueTo="M 33.7 13 L 25 10.2 L 16.3 13 L 10.9 20.4 L 10.9 29.6 L 16.3 37 L 25 39.8 L 33.7 37 L 39.1 29.6 L 39.1 20.4 L 33.7 13"
                        android:valueType="pathType"
                        android:interpolator="@android:anim/decelerate_interpolator"/>
                    <objectAnimator
                        android:propertyName="pathData"
                        android:startOffset="4000"
                        android:duration="1000"
                        android:valueFrom="M 39.1 20.4 L 33.7 13 L 25 10.2 L 16.3 13 L 10.9 20.4 L 10.9 29.6 L 16.3 37 L 25 39.8 L 33.7 37 L 39.1 29.6 L 39.1 20.4"
                        android:valueTo="M 39.7 20 L 32.199 16.173 L 25 12.5 L 17.885 16.13 L 10.3 20 L 10 31 L 16.994 34.031 L 25 37.5 L 32.948 34.056 L 40 31 L 39.7 20"
                        android:valueType="pathType"
                        android:interpolator="@android:interpolator/fast_out_slow_in"/>
                    <objectAnimator
                        android:propertyName="pathData"
                        android:startOffset="5000"
                        android:duration="1000"
                        android:valueFrom="M 10.3 20 L 25 12.5 L 39.7 20 L 40 31 L 25 37.5 L 10 31 L 10.3 20"
                        android:valueTo="M 17.995 24.403 L 25 12.3 L 32.23 24.792 L 39.7 37.7 L 25.581 37.7 L 10.3 37.7 L 17.995 24.403"
                        android:valueType="pathType"
                        android:interpolator="@android:interpolator/fast_out_slow_in"/>
                </set>
            </aapt:attr>
        </target>
    </animated-vector>
    

    My java code for implementing the Animation is as follows:

    final ImageView animationView = (ImageView) findViewById(R.id.animationView);
    final AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable(R.drawable.avd_dice);
    animationView.setImageDrawable(drawable);
    drawable.start();