Variable Fonts in Android O 🖍
After attending DroidCon Italy 2018 last week, I was excited by the presentation from Nick Butcher and Florina Muntenescu. They spoke about many different aspects related to Text on Android including Spans, Colours and AutoSizing TextViews, but the one thing that caught my eye was Variable Fonts.
This was the first time I had heard about variable fonts and I wanted to know more. Since working at Over, we have had to package many different font variations with our (work-in-progress) Android App. Users of the app are able to select the variation of a font family (i.e. the bold version) to overlay text onto their photos. This has increased the file size of the app, so I thought variable fonts could be a good alternative.
So What is a Variable Font? 🔡
A variable font is a single font file that contains a few configuration parameters that expose different variations of the font.
There are many variable fonts that already exist that are lots of fun to play around with. To get an idea of how variable fonts work, take a look at the Zycon font playground as an example.
Why should I care about Variable Fonts? 🤔
Fonts typically need to package a few different variations inside of them to allow for a different type (i.e bold, italic etc) or a font variation that changes how a certain character is displayed.
This can mean you need to download a few different font files in your app, effectively increasing the size of your app/web page.
Implementing Variable Fonts in Android 👩🏻💻
If you are already loading up an OpenType Variable Typeface, taking advantage of variable fonts on Android is a matter of adding one line of code.
In the example below, we load up the
Typeface from the assets folder and then call
setFontVariationSettings on the
Typeface.Builderwith a custom
val builder = Typeface.Builder(assets, "fonts/MutatorSans.ttf")
builder.setFontVariationSettings("'wght' $weight, 'wdth' $width")
textViewFont.typeface = builder.build()
I’ve loaded up two different fonts, Mutator Sans and Zycon that can be seen below.
The Zycon Font exposes a custom “motion” variable that can be set. To create the animation effect as seen above, the
M1 axis is adjusted in a loop.
val builder = Typeface.Builder(assets, "fonts/Zycon.ttf")
builderNew.setFontVariationSettings("'M1 ' $progress")
textViewFontZycon.typeface = builder.build()
Every variable font can define its own parameters that it takes in, so not every font will have an
M1 axis, this is a custom axis defined on this font. The OpenType specification specifies other axes, such as Width, Optical Size, Italic and Slant.
Variable Fonts are currently only available for Android O (version 26) and above. There is no word on if it’ll be in the Android Support Library, which means we can’t use it yet (or we need to hide it behind an Android version check). Let’s hope it comes into the Support Library.
Another gotcha — you probably don’t want to be animating the font change like I’ve got in the example in production. It may cause performance/battery drain issues. It is already stated on the web that animating fonts like this can causes some performance issues.
Last thoughts 💭
Regardless of the gotchas, this is an interesting change that we will hopefully be able to take advantage of soon. Not only in Android development but in Web development as well. This opens up plenty more options for Fonts on Android and will allow us to create smaller APK files and even smaller if we make use of Downloadable Fonts.
Is this a good alternative for me to use right now in the Over app? Not yet unfortunately, we would need to wait for all users to be on Android O (version 26) or hope for this to be implemented in the Support Library. 😔
You can find the source code to this blog post here.
Have a question? Ask me on Twitter.
Over and Out.