With the release of Android 5.0, Google introduced native support for vector images. Unlike their bitmap/raster counterparts, these vector images can be resized without affecting image quality. This allows us to use a single asset across all screen sizes and resolutions - potentially decreasing the size of our app while making our designer's lives a little easier.

Before we dive in to how to create and display these vector images, lets look at what exactly they are and how they differ from bitmaps.

Vector Image

  • Image defined by a geometric equation
  • On Android, saved as a VectorDrawable XML file consisting of a series of Paths and Groups - more on this later
  • Allows an image to change size without affecting quality

Bitmap/Raster Image

  • Image defined by a pixel grid
  • Saved as an image file (PNG, JPEG, etc.)
  • Need multiple versions of the image file to support all devices

Creating a Vector Image

VectorDrawable

Android uses the VectorDrawable class to create vector images. Leveraging VectorDrawable's Path and Group elements, we can define our vector images in XML.

Path - Use to define a path to be drawn. Accepts attributes such as pathData, fillColor, fillApha, etc.

Group - Use to define a group or subgroup of paths. We can then use this to apply transformations such as rotation, pivotX/Y, scaleX/Y, etc.

As an example, here is the XML used to create the above Android logo vector image:



I know what you're thinking - that pathData looks messy. If you're anything like me you're too lazy to write all that by hand. Luckily, you don't have to - that logo was originally an SVG image I converted to a VectorDrawable without writing a single line of code.

Converting Scalable Vector Graphics

Vector images are typically saved in the Scalable Vector Graphics (SVG) format. This is an XML-based open standard developed by the W3C. Most image editing applications support exporting an image as an SVG file. If you have a vector image you'd like to use in your app, it's likely in this format. Android, however, does not natively support SVG images, opting instead to use its own VectorDrawable class.

Luckily, the syntax between the two is very similar. It's easy enough to translate SVG by hand and there are plenty of tools available to convert SVG to VectorDrawable. If you're developing in Android Studio, you can simply go to File > New… > Vector Asset and select the Local SVG File option. Another method is to use an online tool, such as the Android SVG to VectorDrawable converter.

SVG and VectorDrawable are very similar and, with a few exceptions, capable of displaying the same types of images. The two drawbacks to VectorDrawable are that it does not support gradients and it does not support patterns. This means SVG images containing those elements may not convert correctly.

Using a VectorDrawable Image

Once you have your VectorDrawable XML file, you can save it in the drawable directory and use it just like any other drawable asset.



Animating Vector Images

When Google released VectorDrawable, they also released AnimatedVectorDrawable to support animated vectors. AnimatedVectorDrawable vectors can be resized without sacrificing image quality like VectorDrawable while also animating the image.

You will need three things to create an animated vector - a VectorDrawable XML drawable, an Animator, and an AnimatedVectorDrawable XML drawable. Lets check out how all of these come together with some sample code.

VectorDrawable XML

This is just a normal VectorDrawable. If you look at the sample project, you'll notice the VectorDrawable has a Group with the name attribute set to "left_arm". That Group is what we'll be animating - the "left_arm" name will be referenced in our AnimatedVectorDrawable XML.



Animator

If you're already familiar with Animators in Android, this is no different. We will just define an ObjectAnimator in XML, providing it with the property we wish to animate and the specifics of our animation. In the case of our sample project we will be animating the rotation from 0 to -160 degrees, then animating the reverse, and repeating infinite times.



AnimatedVectorDrawable

AnimatedVectorDrawable is the glue that brings everything together. It defines the source VectorDrawable, what targets we'll be animating within that vector, and what Animators we'll be using on each target. In the sample project, we create a target to animate the "left_arm" group using the "arm_rotation" animator.



Performance

We've seen how to create and use vector images and how helpful they can be, but there are some performance implications you should be aware of before deciding to use them for your assets.

Asset Size

One of the main advantages of using a vector image is that we remove the need for multiple versions of the same asset. This should result in a smaller app size. If we examine the sample project, we see that using a vector in place of our bitmap images results in a large size savings from just a single asset.

However, this may not always be the case. Complex images that require lots of paths may actually end up being larger than their bitmap counterparts. Images that have lots of detail or gradients may be best kept as bitmaps.

Rendering

Large and complex vectors will also take longer to render on screen. At runtime, VectorDrawables are first drawn into bitmaps and then uploaded to the GPU for rendering. This process can take significantly longer for very large and/or very complex images. For this reason, it is recommended to use vectors for small and simple images. This makes vectors perfect for icons and buttons.

Caching

When possible, the Android platform will use a cached version of the bitmap generated from your VectorDrawable XML. This cache is invalidated and the bitmap is generated again anytime an image attribute is changed. To utilize the cache as much as possible, avoid changing attributes such as size and alpha unless necessary.

Animation

Because the vector animation is constantly changing, caching isn't used here. This means that each frame of the animation must go through the process of generating a bitmap and uploading it to the GPU for rendering. AnimatedVectorDrawable is intended only for short and simple animations.

Backwards Compatibility

At the time of this writing, there is no native support for vector images below Android 5.0. Google is rumored to be adding these APIs to the support library, but there is no definitive date for when this might happen. In the mean time, there are third-party libraries available that can support vector images as far back as API 4.

Mr. Vector - Supports back to API 14
https://play.google.com/store/apps/details?id=com.telly.mrvector.demo

Vector-Compat - Supports back to API 14
https://github.com/wnafee/vector-compat

SVG Android - Supports back to API 4
https://github.com/pents90/svg-android/tree/master/svgandroid

Closing Thoughts

Vector images on Android are not a silver bullet for eliminating duplicate bitmaps and reducing app size. Replacing bitmaps without consideration could actually end up making your app larger and slower. However, in the right situation, VectorDrawable is a great tool. SVG images with simple paths can be easily converted to VectorDrawable assets - making vector images extremely easy to start using. Additionally, support for animations and a soon-to-be-released addition to the support library all make VectorDrawable worth considering for your app's image assets.

Vector Drawable Demo Project
https://github.com/AMykich/VectorDrawable-Demo