Vector Images Come to Android: What Devs Need to Know
One of the things what confuse many new Android developers is how to support multiple screen sizes in their applications. When it was designed, Android designed to run across many devices with different screen sizes, display resolutions, and pixel densities. Application developers must account for these differences to create a consistent user experience across all devices.
The de facto way to represent images in Android has been using a bitmap. A bitmap represents images as a set of pixels in a grid. While bitmaps offer better performance, due to the computational costs of building and rendering vector images, they also have a severe limitation in terms of image scalability. A bitmap image may look great on a smaller device screen but significantly lose its quality when scaled up for a larger device.
In Android, the typical solution to this problem is to create multiple versions of your images with different dpi (dots per inch) values to support the different screen sizes and densities of the devices your application will run on. Unfortunately, this approach leads to additional time and effort to create the extra assets and more space taken up by your application’s apk file (and the device) to store the assets.
In Android Lollipop ( API level 21), Google finally included native support for vector image assets, allowing for images to be represented geometrically as a set of points, lines, and curves, as well as their associated color information. Vector drawables solve this problem as you only need to create your image once in an XML file and take advantage of its scalability across all display densities for different devices. This not only saves file space, development time and effort, but it also simplifies your application’s maintenance. This effect is amplified in creating animations; instead of having multiple series of bitmap images for different display densities, you can use just your XML files.
No SVG For You
Before Android API version 21 (Lollipop), vector image representation had to be done manually or through the use of various third party libraries working with Scalable Vector Graphics (SVG). SVG, the default vector image representation format for many platforms has been developed by the World Wide Web Consortium (W3C) since 1999. The SVG format still isn’t currently supported by Android (though read on below to learn of a workaround using Google’s Vector Asset Studio).
Although I wasn’t able to find official word from the Android team about the lack of support for SVG, it is fair to assume their reluctance to embrace the standard may be due, at least in part, to performance issues. SVG files can be large relative to the limited memory of mobile devices, and their parsing and rasterization can lead to problems on less powerful mobile processors running on limited power.
Even though support for SVG does not appear to be coming to Android anytime soon but there are many open sources libraries that allow developers to work with SVG files on Android, like the AndroidSVG library. Android’s solution to vectorizing images in Lollipop and newer version of Android (the most recent being Android Marshmallow) are the
AnimatedVectorDrawable classes. I recommend not using the SVG format with your Android apps, instead, consider converting your SVG files to VectorDrawables with the Vector Asset Studio released in Android Studio 1.4.
VectorDrawable class introduced in API level 21 allows you to define a static drawable object using an XML file. As a subclass of the
Drawable class, you can easily integrate VectorDrawables into any of your previous code that uses Drawables, but note that since the
VectorDrawable class was only introduced in Lollipop, it is only available for devices running Android 5.0 and up; there is currently no implementation of the
VectorDrawable class in Android’s support libraries. VectorDrawables share some similarities with the SVG format, using
<path> elements containing its moveto, line, curve, arc and closepath instructions. The
android:pathData attribute uses the same format as the “d” attribute in an SVG path data. To create a
VectorDrawable, the details of its shape must be defined inside a
<vector> XML element.
Another class introduced in Lollipop for vector graphic support is
AnimatedVectorDrawable. Just like the
Drawable but isn’t a subclass of
VectorDrawable as its name may suggest.
AnimatedVectorDrawable allows you to animate the properties of a
VectorDrawable to create an animated drawable. Unlikely VectorDrawables which need only one XML file,
AnimatedVectorDrawable objects typically required an XML file for the
AnimatedVectorDrawable, but also two other files, one for the
VectorDrawable being animated and another for the Animator (a
AnimatorSet). As with the
VectorDrawable class, there is currently no Android support library implementation of the
Vector Asset Studio
In Android Studio 1.4, Google added a new tool to better support vector assets, the Vector Asset Studio. With this feature, importing SVG files is made easier and you can now use any of the material design icon vector assets provided by the software. The Vector Asset Studio generates a XML file for your VectorDrawable using either the data from a SVG file or the material icons provided by the Google material design specification.
Although Vector Asset Studio supports the essential standard of the SVG format, it does not currently support all SVG features, something you should keep in mind when importing your files. If an error is encountered during the importation process, simplify your SVG file and try again.
As vector asset support with the
AnimatedVectorDrawable classes was only added in Android Lollipop, released just 13 months ago, it is not directly supported by the vast majority of Android devices. Most Android developers support a minimum API level lower than version 21 so there is a need for additional vector asset support for older devices.
Although there is no official support library for vector assets from the Android team, the Vector Asset Studio can generate appropriate PNG files for various pixel densities at build time. To enable this, your must use version 1.4.0-beta3 of the Gradle Android plugin (or higher, with revision 1.5.0 being the latest stable version). Note that some limitations exist; there is currently no support for
<clip-path> elements, and your XML vector file cannot contain references to other resource files for the PNG files to be generated.
As previously mentioned, a number of third-party libraries currently exist to enable developers to work directly with SVG files, but there are also tools to enable pre-Lollipop devices to work with VectorDrawable XML files. The vector-compat library by Wael Nafee is an open source project that adds
AnimatedVectorDrawable support for pre-Lollipop devices down to Android API version 14. The library also intelligently falls back on the official
AnimatedVectorDrawable implementation on devices with Lollipop or higher versions of Android.
As Android is primarily a mobile device operating system designed to run on devices with limited power, memory and processing speed, a number of considerations should be made before choosing to use vector assets. VectorDrawables are most appropriate for smaller, simpler images like icons. If your image is large or very detailed a PNG or NinePatch image may be better suited. The Android Developer reference recommends that a vector image be limited to a maximum of 200 x 200 dpi, as the initial loading of a vector graphic can be relatively expensive, leading to long draw times.