Plain English please
According to Android's documentation:
A VectorDrawable is a vector graphic defined in an XML file as a set of points, lines, and curves along with its associated color information.
We use them for the simple reason that they will display on any screen dimension at any size with minimal loss of quality. Before, the only way to guarantee that a graphic would display properly on different screens sizes and densities was to create many sizes of that graphic. Now, we can have one xml file that we can use wherever we want at what ever size we want.
The second advantage is that using Vector Drawables can dramatically reduce the size of an apk.
The basic workflow
In general, to get an image to become a Vector Drawable, we start with an SVG. SVGs and Vector Drawables aren't the same thing. But the SVG standard shares many similarities and is widely used, so it's the best starting place.
Vector Drawable are generally created from converted SVGs. The conversion takes the building blocks of the SVG and converts it into XML. That XML is what Android uses to build the graphic and display it. You could write the XML from scratch but unless it's a super simple shape, that would be a very difficult and time-consuming effort.
Vector Drawables do not support everything that SVGs do. This means that you need to take some care when creating them. The general principle is to keep them as simple as possible.
When to use a vector drawable
One of the hurdles for me when first exploring vector drawables was understanding when I should or shouldn't use them.
To help with this I've come up with a few general rules below.
Note! I'm basing these on a combination of factors, such as:
How long it would take me to produce them and the trade-off of the benefits.
My personal limitations with vector design (I'm not the strongest illustrator).
The limitations imposed by vector drawables.
1. My graphic is simple
Using Vector Drawables can dramatically reduce the APK size of an app. But rather than the app serving up a pre-rendered bitmap image, it now needs to take XML file, parse it and draw the graphic. When the graphic is simple it can easily handle that and its effects on performance are negligible. However, if the graphic is complicated it could become noticeable to the user. Icons are ideal, large illustrations of cityscapes are not.
2. It doesn't contain gradients or patterns
Vector Drawables don't support gradients or patterns. If your graphic relies on them then default back to providing multiple sized assets.
3. It doesn't contain text
Vector drawables don't support text. They can only define lines, curves and colours.
Now, if the text is very simple it could be worth converting it to paths. However, I'd hesitate to do that for 2 reasons:
- You can't translate the text. If your app is going to be translated it might be worth not embedding the text into the image and overlaying it instead in code.
- If there are anything more than a few characters, when you convert it to paths you could have a lot. We want our drawables to be simple to ensure that they are performant. Too many paths and you will lose the benefits.
Prepping my SVG in sketch
Points and pixels
Wherever possible it's good practice to put the points of your vector on whole pixels. This means that the value the XML file holds to describe the position of that point is as short as possible. In the example below you can see the difference between 2 examples of simple lines. But imagine that across many points and you can see how that file would get really big quickly.
This is simple, but make sure you have "Round: Full Pixels" on.
Vector drawables don't handle transforms. I always make sure that I've removed any by flattening the svg before exporting it. I get caught out by rotations in my SVGs quite often. The Vector Drawable won't recognise the rotation and will just reset the shape to zero.
Make sure artboard sizes are correct before exporting as they define the width and height of your Vector Drawable. For example, icons often need padding around them so make sure the artboard reflects that.
Convert to outlines
Vector Drawables don't support dashed lines. The easy way around this is to take convert the dashed line shape to outlines. That way the Vector Drawable will plot each segment of the dashed line.
You’ll find this in sketch at: Layer>Convert to Outlines
It can be useful to pull across the naming of your layers into the XML so that it is clear what each part is. With that being the case, proper naming of your layers is important. If there's more than one rectangle, calling them all 'rectangle' isn't going to help you later.
I export my SVGs with the name that I would like them to be in Android Studio. i.e. ic_launcher.svg. That helps me keep track of the right assets when converting them.
I've tried using the built in tool for vector conversion in Android Studio but found it a little clunky. There are some big changes hinted at for the next release, but for now I'm using an online tool:
This tool is great and quick. You upload your SVG to it and it generates the XML for you.
There are, however, a few things to note:
- Check the box for: "Remove empty groups without attributes". This will keep your XML more efficient.
- Check the box for: "Word-wrap pathData". This avoids Android Studio throwing warnings at you for code lines being too long,=.
- Check the box for: "Import IDs from SVG as name". This helps you identify which parts of the XML are which.
- It often adds the XML attribute: android:fillType="evenOdd". That attribute is only supported by Android API level 24 and above (i.e. Android 7.0 Nougat). I've found that often you can remove it and it still seems to work fine, but you definitely should manually test it to check. Evenodd can be used intentionally and there is more info about it here.
Testing your vector drawable is important to make sure that you are producing the file that you want. It’s especially important if you are giving that file to a developer to implement, you want to be certain it’s correct like any other asset provided.
I’ve produced a video below that takes us through how to test a vector drawable in Android Studio.
Nick Butcher is a leading expert in this area and his video from DroidCon NYC 2017 is a must watch if you want to explore further: https://www.youtube.com/watch?v=itwOSMVlHaY