October 30, 2017

Fonts as a Resource

The introduction of API 26 brought a lot of great features to the Android OS. One specific feature that has been lacking (and a thorn in my…

Fonts as a Resource

The introduction of API 26 brought a lot of great features to the Android OS. One specific feature that has been lacking (and a thorn in my side) is proper font support. If you were lucky enough to just need legacy support, like Roboto, then something like johnkil/Android-RobotoTextView would suffice. However, different projects have unique design languages which translates to various typefaces. These same typefaces are not bundled with the Android OS by default, finding yourself in a situation with having to roll your own solution. To top that off, you could never preview the typeface in question in the IDE layout editor.

Before API 26

If you wanted to roll your own fonts you’d probably do something like the following:

Step 1. Add your OTF/TTF files to assets
Step 2. Create a custom view to support said OTF/TTF files
Step 3. Create some construct in XML to reference each file to then reference in your Layout files
Step 4. Create style attributes for your View that support said construct
Step 5. Read in the typeface value and fetch that typeface within your View
Step 6. Cache that typeface in some sort of static map to prevent loading in the same font file multiple time
Step 7. Made sure to prevent fetching typeface if View.isInEditMode() returns true so that the editor is able to render the view…with the typeface actually rendering
Step 8. Create any subclasses of TextView you’d need (e.g. EditText, Button) to enable font support for those View elements.
Step 9. Profit??

With the introduction of DataBinding, that process is cut down by a bit. You wouldn’t need to roll your own custom view anymore but you’d still be responsible for caching the typeface file. On top of that, the hassle around adding and referencing each typeface file is still there.

API 26+

With API 26, supporting fonts are drastically simpler to do.

Step 1. Add your OTF/TTF files to res/font
Step 2. Reference that file using android:fontFamily attribute on anything that extends TextView. (e.g android:fontFamily="@font/comic_sans")

Thats it, the typefaces are cached internally and it works on all subclasses of TextView out of the box … all the way back to API 14!

More info here.

Time to apply comic-sans to all the things!


Small note: Let’s say you find yourself interrogating a TypedArray for a font but are on an API < 26. Instead of calling TypedArray.getFont() //API 26) you can get the font resource id via TypedArray.getResourceId() and fetch the resource using ResourcesCompat.getFont().

Enjoy!