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.
- 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
- 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
Android uses the
VectorDrawable class to create vector images. Leveraging
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
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.
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.
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
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 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.
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.
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.
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.
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.
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.
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
Vector-Compat - Supports back to API 14
SVG Android - Supports back to API 4
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