Animation / Drawable / VectorDrawable

AnimatedVectorDrawable Bundles

Those that know me and regular readers of Styling Android will be already know that I have a particular passion for moving stuff around, and animating all the things! Quite predictably I’m a big fan of AnimatedVectorDrawable and there was a small addition to this most useful of components that was announced an Google IO 2016 but bypassed many of us, myself included. That is until Nick Butcher posted about it. The feature itself is fairly minor, but helps to keep our code self-contained and therefore easier to maintain – it is a different way of packaging AnimatedVectorDrawable at source level. In this article we’ll take a look at AnimatedVectorDrawable Bundles.

Those familiar with AnimatedVectorDrawable will be aware that an AnimatedVectorDrawable consists of a minimum of three separate files (but it can be many more): The first containing a <vector> definition which is the VectorDrawable which is going to be animated; then there are one or more <objectAnimator> definitions which are the animations that we wish to apply; the final file is the <animated-vector> definition which ties the animators to the components of the VectorDrawable. For a full description please check out VectorDrawables – Part 2. Having all of these files dotted around can make it difficult to understand what an AnimatedVectorDrawable is doing – and this is particularly true when it comes to code reviewing AnimatedVectorDrawable implementations.

AnimatedVectorDrawable Bundles are simply a mechanism for combining these components in to a single file. The syntax is very similar to what we’re familiar with, so there’s nothing much more to learn. However there are a couple of things worth considering to ensure that we make the best use of this new feature.

Before we dive in to the code, let’s first discuss how these Bundles are actually implemented. Our bundles actually get broken in to their components by AAPT during the build – so what actually goes in to the APK is actually identical (with some caveats, which we’ll cover later). All that the bundle format allows us is just code organisation. In order to use bundles you must use Build Tools 24.0.0 or later.

So let’s start with a simple AnimatedVectorDrawable which animates between a plus and minus symbol:

animated-vector

This consists of a VectorDrawable:

Two Animators, the first performs the pathData animation:

And another Animator to perform the rotation:

These are all tied together by the AnimatedVectorDrawable:

The Bundle format allows us to combine all of these in to a single file:

This follows the structure of the XML format, but we just embed the other files in to this by using a declarative attribute. In the traditional format we need to include a android:drawable attribute on the element; but in the Bundle format we can declare this attribute inline using <aapt:attr name="android:drawable"> as we have in line 7. Similarly we need to declare the two android:animation attributes inline as well – lines 35 & 54.

One thing worth noting is that we need to use the aapt namespace for attribute inlining. The other thing that you’ll find if you try this is that Android Studio will show lots of errors on this because it does not yet recognise the bundle format. Also lint will throw errors for the same reason so I needed to add the tools:ignore="MissingPrefix" suppression at line 5.

So that’s simple enough, but what about the caveats I mentioned earlier? Currently there does not to be any duplication detection in the AAPT pass – so if we use the same animation multiple times then each inline occurrence will be stripped out to a separate file – therefore we’ll bloat our APK with lots of duplicate animator files if we inline everything. It is worth bearing this in mind and be diligent when using bundles to avoid lots of duplication.

Once trick that we can use is we can mix and match the traditional structure and bundle structure even within the same file. For example the following is perfectly acceptable:

We’re using the bundle structure for the drawable and one of the animator attributes (the path animator which is specific to the drawable), and the traditional structure for the other animator (a much more generic rotation animator). By doing this we can share common components where necessary, and inline the one-off components.

That’s really all there is to it – Bundles are pretty useful, but it’s worth being mindful the potential APK bloat issue from duplicated resources.

The source code for this article is available here.

© 2016, Mark Allison. All rights reserved.

CC BY-NC-SA 4.0 AnimatedVectorDrawable Bundles by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *