Fonts

Fonts (revisited)

In a previous series we took an early look at the new font support coming in Android O. At Google IO 2017 the new font support was formally announced, and in this article we’ll take a look at what has changed since the original series.


Source
Previously we took a look at how we can directly use custom fonts directly in our layouts, but there were two main issues: Firstly, the mechanism for specifying different font styles (such as bold and italic) did not work; secondly this was only supported in Android O with no backward compatibility. There are some updates for both of these issues and, in this article, we’ll take a deeper look.

The first of these issues is the fact that font styles were not fully implemented in the initial O developer preview. As I said in the previous article there was either a bug or an incomplete implementation at that stage. But this has now been fixed and we can now specify different variants using the android:textStyle attribute:

If we run that we can see that the different variants now render correctly:

So what about the backwards compatibility issue? That’s a mixture of good and bad news. The good news is that version 26.0.0-beta1 of support-v4 library now includes support for including custom fonts in your APK and defining them as XML. First we need to add this dependency and reduce the minSdkVersion:

I also dropped targetSdkVersion because it won’t install on pre-O devices if we target the O preview.

The only caveat to declaring our fonts in XML is that we must declare your typefaces using both the android and app namespaces to ensure full compatibility:

(Note: how the UnusedAttribute warning is suppressed otherwise lint warns that the attributes in the android namespace are unused.

Finally we need to change how we apply our typeface programmatically to use ResourcesCompat to load the Typeface:

If we run this on a device running the O developer preview, it appears as before. However, if we run this on a device running Marshmallow (API 23) we get the following:

Although the correct styles have been applied, it is only the final TextView which has had the correct font applied and this is the one to which we applied the Typeface programmatically. In the official documentation there is mention of applying things programmatically, but nothing with regard to whether specifying a font using the fontFamily attribute in XML is supported.

There is actually a real gotcha here. In order to keep the example project as lean as possible, the original implementation targeted Android O only and, as a result of this approach, my MainActivity subclasses Activity. However, it seems that for the support library fonts support we actually need to use AppCompat and subclass AppCompatActivity. For those that understand how AppCompat works this will make perfect sense, but for those that don’t: AppCompat uses a decorator pattern around existing view types and has its own view inflation mechanism to substitute these in during layout inflation. It is using this mechanism that the font support has been added, so things simply don’t work unless we are using AppCompat.

So, we must convert our project. First our Activity:

Next our theme:

As well as changing the parent theme, we must also remove the android namespace from our item names.

Finally our build script:

If we do this, we now have the correct fonts being rendered. However, there is something of of a discrepancy in how the weights are rendered on O compared to earlier versions:

The bold fonts in Marshmallow (on the left) are not quite as strong as those for Android O (on the right) this has been raised as an issue. Moreover, the weights of the bottom two TextViews in Marshmallow should be identical, but they are not. This would suggest a bug in how weights are being applied via XML. Hopefully this is also something which will get resolved before we have a final version of the support library.

So the fonts support has improved quite considerably and are certainly useable (provided you are using AppCompat), but there is still one minor wrinkle.

The source code for this article is available here.

© 2017, Mark Allison. All rights reserved.

CC BY-NC-SA 4.0 Fonts (revisited) by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *