Using the new and improved AnimatedVectorDrawable to pause and seek your animations.
Android SDK 21 introduced both the VectorDrawable and the AnimatedVectorDrawable. This allowed you to use vector assets within your app, and even animate them.
They've iterated on these since then, but AnimatedVectorDrawable was still missing something. You couldn't manipulate and control the animation. There was no pause or seek functionality.
The Android team has been hard at work backporting the framework Animator APIs. They have created a separate unbundled AndroidX library called Core-Animation.
The Animator APIs have been around for some time. But they didn't provide the capabilities needed for this pause and seek functionality. So they needed to be unbundled and then iterated on.
Once Core-Animation was available the Android team could create the Vectordrawable-Seekable library. This library revolves around the class SeekableAnimatedVectorDrawable.
Under the hood, this class uses the AnimatorSet and subsequently Animator from Core-Animation. These provide the pause and seek functionality.
Firstly, you need a vector asset of the image you wish to animate. This works best if it is simple and optimised.
See these resources for information on optimising assets:
- https://www.brightec.co.uk/blog/creating-vector-drawables-android
- https://arturdryomov.dev/posts/optimizing-android-vector-images/
For this example I am going to use an Android:
This XML file should be placed in your res/drawable directory.
Notice the group names, as these allow us to reference each part of the image later. Notice also the pivot points defined. These define the pivot around which rotation would happen.
To define the animation itself you can create another XML file. This defines an ObjectAnimator.
This file goes into your res/anim directory.
You can see from the attributes that this is a rotation animation. It will repeat infinitely by going forward and then reversing and going backwards. It will rotate from 180° to 220° over 600 milliseconds each repeat.
We can combine these two into an animated-vector. This can again be defined within an XML file.
This XML file should be placed in your res/drawable directory.
This file connects the image and animation. The drawable is defined near the top. The animation rotation is targeting the arm-left.
You can now use this animated-vector to display your animation on the screen.
Either set it on your ImageView via:
app:srcCompat="@drawable/img_android_animated"
Or you can define it programmatically:
val drawable = AnimatedVectorDrawableCompat.create(this, R.drawable.img_android_animated)
imageView.setImageDrawable(drawable)
drawable.start()
Instead of creating an AnimatedVectorDrawable from your XML, create a SeekableAnimatedVectorDrawable:
val drawable = SeekableAnimatedVectorDrawable.create(this, R.drawable.img_android_animated)
imageView.setImageDrawable(drawable)
drawable.start()
Now you have access to pause seek functionality.
Play/Pause
drawable.pause()
drawable.play()
Duration
drawable.totalDuration
Note for infinite animations this will return -1.
Current Time
drawable.currentPlayTime
This can be both gotten and set. If you set this value, the animation will be set to that time and continued if it was already running.
These new API's provide some interesting functionality. It unlocks some very cool and delighting animations.
Both Core-Animation and Vectordrawable-Seekable are in alpha at the time of writing. It is worth noting that Core-Animation is mostly a backport of the existing framework API's. So arguably it should be more stable than a usual alpha release.
https://developer.android.com/jetpack/androidx/releases/vectordrawable
https://developer.android.com/jetpack/androidx/releases/core
Now you can pause and seek to your heart's content.
Search over 400 blog posts from our team
Subscribe to our monthly digest of blogs to stay in the loop and come with us on our journey to make things better!