AnimatedVectorDrawable/ObjectAnimator startoffset bug?

1.8k views Asked by At

I want to animated a VectorDrawable.

Here is my VectorDrawable (converted from SVG, simplified for this example):

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="888dp"
        android:height="600dp"
        android:viewportHeight="600"
        android:viewportWidth="888">

    <group
        android:name="wheel"
        android:pivotX="498.0"
        android:pivotY="385.0"
        android:rotation="0.0">
        <path
            android:fillColor="#BDEDFF"
            android:pathData="M547.4,363.9l-23.7,6.7c-1.1-1.8-2.5-3.5-4-5l12-21.5c2.2-3.9,0.8-8.9-3.1-11.1c-3.9-2.2-8.9-0.8-11.1,3.1
l-12,21.5c-2-0.5-4.2-0.7-6.4-0.8l-6.7-23.7c-1.2-4.3-5.7-6.8-10-5.6c-4.3,1.2-6.8,5.7-5.6,10l6.7,23.7c-1.8,1.1-3.5,2.5-5,4
l-21.5-12c-3.9-2.2-8.9-0.8-11.1,3.1c-2.2,3.9-0.8,8.9,3.1,11.1l21.5,12c-0.5,2-0.7,4.2-0.8,6.4l-23.7,6.7c-4.3,1.2-6.8,5.7-5.6,10
c1,3.6,4.3,5.9,7.8,5.9c0.7,0,1.5-0.1,2.2-0.3l23.7-6.7c1.1,1.8,2.5,3.5,4,5l-12,21.5c-2.2,3.9-0.8,8.9,3.1,11.1c1.3,0.7,2.6,1,4,1
c2.9,0,5.6-1.5,7.1-4.2l12-21.5c2,0.5,4.2,0.7,6.4,0.8l6.7,23.7c1,3.6,4.3,5.9,7.8,5.9c0.7,0,1.5-0.1,2.2-0.3
c4.3-1.2,6.8-5.7,5.6-10l-6.7-23.7c1.8-1.1,3.5-2.5,5-4l21.5,12c1.3,0.7,2.6,1,4,1c2.8,0,5.6-1.5,7.1-4.2c2.2-3.9,0.8-8.9-3.1-11.1
l-21.5-12c0.5-2,0.7-4.2,0.8-6.4l23.7-6.7c4.3-1.2,6.8-5.7,5.6-10C556.2,365.1,551.7,362.6,547.4,363.9z"/>
    </group>
</vector>

My AnimatedVectorDrawable:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/image_vect">
    <target
        android:name="wheel"
        android:animation="@anim/wheel"/>
</animated-vector>

My animation:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="1000"
        android:propertyName="rotation"
        android:startOffset="1000"
        android:valueFrom="0"
        android:valueTo="180"
        android:valueType="floatType"/>
</set>

My issue is with startOffset:

  • if android:startOffset is 100, the animation is playing on both 4.4 and 6.0. Perfect.

  • if android:startOffset is 300, the animation is not playing on 4.4 and it's playing on 6.0

  • if android:startOffset is 500, the animation is not playing on 4.4 neither on 6.0

Am I doing something wrong?

Thanks for your help!

Ps: my final vector contains more elements and my animation contains more steps (turn right, then turn left after a delay, then …). But this simplify version is enough to show the error I'm facing.

3

There are 3 answers

2
Lewis McGeary On

I've found startOffset to be generally problematic with AnimatedVectorDrawables, enough so that I just avoid using it.

The alternative approach being to include an ObjectAnimator of the required length keeping the property at the next starting value. In this case:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">
    <objectAnimator
        android:duration="1000"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="0"
        android:valueType="floatType"/>
    <objectAnimator
        android:duration="1000"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="180"
        android:valueType="floatType"/>
</set>
0
Slugged Germ2 On

In my case, the error was facing only the second time I asked for the animation. I was re-initializing the animation every time, and for me the problem has been solved simply initializing only the first time. So, this code:

playAnimation = (AnimatedVectorDrawable) getDrawable(R.drawable.play_anim);
m_imageview_animable.setImageDrawable(playAnimation);
playAnimation.start();`

became:

if (playAnimation == null){
     playAnimation = (AnimatedVectorDrawable) getDrawable(R.drawable.play_anim);
     m_imageview_animable.setImageDrawable(playAnimation);
     playAnimation.start();
}
0
Damon Baker On

I also encountered this incredibly frustrating bug. It was reported to Google's issue tracker in December of 2016 but I am doubtful they will ever get around to fixing it.

The workaround I used is similar to the answer given by Lewis McGeary, but as pointed out in the comments this will not work if you want to animate multiple properties at the same time (E.g. scaleX and scaleY).

What you can do however is wrap the animations you want to animate together inside another <set> like so:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <!-- Dummy animation to replace startOffset -->
    <objectAnimator android:duration="250" />

    <set android:ordering="together">
        <objectAnimator
            android:duration="450"
            android:interpolator="@android:anim/overshoot_interpolator"
            android:propertyName="scaleX"
            android:valueFrom="0"
            android:valueTo="0.8"
            android:valueType="floatType" />

        <objectAnimator
            android:duration="450"
            android:interpolator="@android:anim/overshoot_interpolator"
            android:propertyName="scaleY"
            android:valueFrom="0"
            android:valueTo="0.8"
            android:valueType="floatType" />
    </set>
</set>