Scaling to Infinity
When I make an app, I spend my time between two worlds.
In the first, I produce sequences of meaningul characters for a virtual machine in your favorite IDE, Xamarin Studio. In the second, I use my best friend Inkscape (and lately also Affinity) to help me think, iterate and produce the front face of my app.
The main challenge of this form of development is to find the best way to ease the content transition between both worlds.
In Android, what’s essentially the apocalypse of screen form-factor makes it particularily painful to work with that visual assets part of your app.
Where the world was happily spread between
hdpi a few years back, today we just don’t know how many ‘x’ we are going to be able to fit in front of ‘hdpi’ (at the time of this writing we reached
I have actually already talked about this subject and, at the time, released my own library to try to tackle this issue.
But today we can finally rejoice as Google gave developers a blessed way to create unlimited scalable graphics with the recent release of Lollipop (or Android 5.0).
This new types of drawable is unoriginaly called Vector Drawables and, as with any other drawable, they are natively understood by the Android toolchain which make their use as seamless as feasible (i.e. you can reference them in layouts, styles, acquire them through
This is an example of a vector drawable (store them in your
<?xml version="1.0" encoding="utf-8" ?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="96dp" android:width="96dp" android:viewportHeight="48" android:viewportWidth="48" > <group> <path android:fillColor="@color/black_primary" android:pathData="M12 36l17-12-17-12v24zm20-24v24h4V12h-4z" /> </group> </vector>
Which draws this well known media player action icon:
The beef of a vector drawable is in its various
<path/> elements and more precisely its
pathData attribute. As arcane as it may look, it actually defines the full blown shape of the icon in the very concise SVG Path data format.
Don’t worry too much though, you won’t have to write that down by yourself (you may need to tweak it though for more funky things but more on that in a later post).
Since it’s based on the same specification than used in SVG itself, as long as you can grab a SVG version of your graphic you will directly be able to copy and paste it into a vector drawable XML.
As a matter of fact, the icon example that I pasted above came from Google’s official material design icon pack which also contains SVG for every icon:
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"> <path d="M12 36l17-12-17-12v24zm20-24v24h4V12h-4z"/> </svg>
Notice also how the
viewportWidth values in the vector drawable reflect what’s in the width/height/viewBox parameter of the SVG. As long as those values are correctly defined, you can play with the
android:height part of your drawable the way you want.
Together with the new general tinting facility in Lollipop, you can now iterate over your assets even faster without leaving your IDE and without having to re-generate 6 variants of your graphics.