Android dev tip: Custom fonts for TextView

So your designer friend is back and she drops you a hot new design.  Due to a branding declaration from a highly-paid branding consultant, your whole app needs to use this new typeface.

Screen Shot 2016-05-24 at 8.01.33 AMOk, probably not the whole app, just a few titles.

Here’s the catch though — Android doesn’t ship with hot new typefaces like Uptown Sans, so you have to figure out how to convince TextView to render with it.  The goal is to make setting the font as easy as every other attribute on a TextView.  

before-customYeah, lint is having none of that; see the highlight?  And it’s just going to be ignored by TextView.  But hang with me for a couple minutes and you’ll get there.

Step 1. Copy your .otf into your assets folder

assets-folderStep 2. Copy this class into your project… Build… Breathe… we’re almost there…

We don’t want to go to the effort of rewriting TextView from scratch, it gives us so much.  We just want it to accept custom fonts from our layout XML.  So we extend.  Embrace, extend… embiggen? It’s something like that, I’m pretty sure.  Enfranchise?  Embark?  Empower?  Yeah, empower, that has to be it.

Step 3. You need to add this to your attrs.xml, or create res/values/attrs.xml with this if you don’t have one already

Step 4. Back to the layout file – but with two adjustments

layout

That’s it.  Build & run, and you’re done.

Extra Credit.

But wait, you say.  DRY that up, right?  Yeah, let’s do.  You don’t want to have the type in the whole path to the font in every layout file, isn’t that what auto-complete is for?  So let’s kick it up a notch.  Now I want two weights of that typeface, and the ability to easily reference one or the other.

We need to adjust your attribute to be an enum, instead of a string.  Here’s the new version:

Then in the custom TextView, we can dereference those.

And we’re there.  See?  Not that hard.

Yeah, so…

  • “There are other ways to do this!”
    • Agreed.  There are others like it, but this one is mine.  Tweet @ me with better solutions.
  • “Why not just use a TextView in the XML and use setTypeface() to change the typeface?”
    • You totally could.  I prefer to keep layout stuff in my layout files for code architecture reasons.

 

What did I miss?  Seriously, tweet @ me.  Half of the reason I wrote this article was because this feels like way too much work, so if you’ve got a better solution that I overlooked, I’d love to hear about it.