javaandroidandroid-animationandroid-vectordrawableobjectanimator

Programmatically start Animatable (AnimatedVectorDrawable) at a particular offset


Is there a way to programmatically start an AnimatedVectorDrawable at a particular offset?

Context:

I'm developing for API 19 and up, so I'm using Android Jetpack. I have a custom View with an animatable "indicator" (a <selector> with vector images).

The way I currently start my animation is as follows:

ImageView indicator = findViewById(R.id.indicator);
indicatorDrawable = indicator.getDrawable().getCurrent();
if(indicatorDrawable instanceof Animatable) {
    ((Animatable) indicatorDrawable).start();
}

And this is the animator, associated with my "indicator", in xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="500"
        android:propertyName="fillAlpha"
        android:valueFrom="0.5"
        android:valueTo="0"
        android:repeatMode="reverse"
        android:repeatCount="infinite"/>
</set>

This all works fine. However, I have multiple instances of my custom View in an Activity and I need to synchronize their "indicator" animations (which can individually switch on or off at any time).

I won't bother you with the details, but I currently have an acceptable solution that basically uses a static millisecond field in my custom View. It works, but it causes the animations to stall for some time, if they are trying to catch up.

I'd much rather immediately start the animation at a particular offset, to avoid this stalling.

I would think I should somehow be able to access above ObjectAnimator associated with my Animatable, and set its startOffset, but I can't figure out how.


So, can I somehow access the ObjectAnimator and individually set its startOffset for each individual Animatable, programmatically?


Solution

  • After some additional searching on the interwebs I found the library Kyrie, by Alex Lockwood, which suggests the following about the standard implementation of VectorDrawable and AnimatedVectorDrawable:

    However, these two classes have three main limitations:

    1. They can't be paused, resumed, or seeked.

    ... and addresses those issues.

    Then, after some more searching, I came across a new Android Jetpack package, androidx.vectordrawable, that addresses these issues as well, in particular: androidx.vectordrawable:vectordrawable-seekable:1.0.0.

    Therefore, it appears it simply is not possible to seek to a particular offset with the default implementation of AnimatedVectorDrawable.

    So, now I just have to figure out how this new Android Jetpack package works and see if it's worth the additional overhead.