The Android Developer’s Guide to Better Typography
Typography can make a big difference in the attractiveness and usability of an app, and now Android developers can use typefaces from the Google Fonts catalog. It’s simple, efficient, and opens up a range of new typographic options.
Every developer knows that design plays a major role in user experience—it can be a critical factor in the success or failure of your app. Still, there’s always the temptation to use default fonts, whether to push ahead with a release, to sidestep the complexity of integrating custom fonts, or just to avoid the seemingly arcane art of type selection.
Luckily, Android Studio has made it easier to build an app with distinctive typography using the new “Downloadable Fonts” feature. This feature puts the full Google Fonts catalog at your fingertips and makes it easy to customize typography on JellyBean and later (SDK level 16+) with free, reliable, high-quality Google Fonts.
Beyond aesthetic improvements, using downloadable fonts can also reduce the overall size of APK files, and decrease memory usage, because downloaded fonts will be shared among all applications. Your APK will be smaller because it doesn’t need to bundle the fonts upfront. Once a font is downloaded from Google Fonts for one app, Android keeps it on disk so other apps can use it too without any additional storage. Just like our web API, which serves fonts directly to websites, the more that people use Google Fonts, the greater the latency gains from sharing.
In this tutorial, we’ll improve the typography of a sample application by switching out the standard font for something with a more distinctive and dynamic range of styles from the Google Fonts catalog. We’ll use a typeface called Alegreya, which is known as a “super family” because it offers a wide range of styles, weights, and variants. Using a super family means we will have plenty of typographic options to fine tune the appearance of our interface.
The app we’ll work with is Plaid, by Nick Butcher, which is a scrollable feed of Material Design related news articles. These are presented as full-bleed tiles, which you can tap or click to expand into a ‘dribble’ page with favoriting and stats for ‘likes’ and ‘views.’
This tutorial is intended for developers, but it also explains some of the “why” decisions behind the design, so hold on to both hats!
Before We Get Started
Install Android Studio 3.0, then clone the “Plaid” project from Github and checkout b76937, the version we’ll be using for this tutorial:
git clone https://github.com/rsheeter/plaid.git;
git checkout b76937;
Now open the project in Android Studio 3.0.
In order to use the Google Fonts provider, you must have Google Play Services version 12+ installed. If you’re working with a device that’s set up to receive updates, you can skip ahead; but if you’re using an emulator launched through Android Studio, it might be using an older version of Google Play Services. To update the Android Virtual Device from Android Studio, follow these steps.
1. Create a virtual device (Tools > Android > AVD Manager) with Play Store, indicated by the icon in the Play Store column:
2. Start a virtual device in Android Studio. To open the “Extended Controls,” on the right side of the emulator screen, tap or click the final
... icon at the bottom of the vertical button panel:
Google Play and check the version number. If you’re running
11.2 or lower, tap or click the
Update button. This should take you to the Play Store, where you should then tap or click its green
4. Now that you’ve updated to version 11.2 or higher, the device will support downloadable fonts.
Update the About Page
First, let’s update the About page. The “body text” paragraph in the lower half of the page is currently set in Roboto Regular, a sans font, while the title (in the top half) is set in Roboto Mono Regular. Let’s switch it to the serif typeface Alegreya, an energetic, contemporary design with a dynamic and varied rhythm inspired by calligraphic letterforms. The Alegreya type system is a “super family,” originally intended for literature, and includes serif and sans-serif sister families.
The title text serves as a “hero image,” a large graphic that leads people into the page and sets an emotional tone. This uses the title’s letterforms as a “mask” that cuts out the mint green foreground so an image can peek through from behind. Switching from Roboto Mono Regular to Alegreya Black will provide a larger surface area for that image to shine through.
Style the “About Activity” text
Since the “About Activity” text currently calls for the “default” text style, Roboto Regular, we’ll have to set another one manually:
- Select the
- In the
Component Treepanel, open
- In the
Attributespanel, open the
fontFamilydropdown and select
More Fonts…(You may have to click
View all attributesto see
- Select family
- Select style
Android Studio has configured our app to retrieve the font from the Google Fonts ‘provider.’ In order to do so, it made a number of changes to our source tree:
app/src/main/res/font/ (learn more)
This new directory contains XML files describing font resources. In this case, it gives instructions for loading a Typeface from the Google Fonts Provider.
app/src/main/res/values/font_certs.xml (learn more)
To ensure that font requests are only answered by trusted parties, this file specifies the signature of the font provider.
app/src/main/res/values/preloaded_fonts.xml (learn more)
This is a list of fonts to load early in application startup. Corrected 4/12/2018; previously erroneously indicated these fonts load at install time.
app/src/main/AndroidManifest.xml: <meta-data android:name="fontProviderRequests" android:value="Lobster"/>:
This is a list of fonts the Google Fonts provider will try to load at app install (or update) time.
You can see a sample diff for this step in commit a1e711c.
Update the cutout text view
The text style is currently Roboto Mono Regular. Let’s change it by continuing where we left off in the previous step:
7. In the Design view, select “CutoutTextView”
8. Open the “fontFamily” dropdown and select “More Fonts…”
9. Select family “Alegreya”
10. Select style “Black”
11. (For step 11, see below)
If you tried this right now, the font would still be Roboto Regular, not Alegreya Black. The reason is that declarative fonts are fetched asynchronously by default (learn more.) On completion, the system will try to update the font of a TextView using setTypeface, but this will fail because CutoutTextView does not extend TextView.
However, CutoutTextView does implement the fontFamily property (here). If we mark the font fetch as blocking, then the fontFamily will be ready when we ask for it. If we don’t mark it as blocking, the value returned for fontFamily won’t be usable yet. (We could also code async fetch ourselves, but let’s save that for later.)
Now try it out! (You can see a sample diff for this step at commit f1c997)
Take a look at the “About” text. It’s grey on a somewhat lighter grey background. Alegreya is a serif typeface with high ‘stroke modulation,’ meaning that its letterforms vary widely from their thickest to their thinnest points. Somewhat counterintuitively, this leads to lower visual contrast overall. Fine variations in a letterform can make it appear blurry, especially at small sizes.
To mitigate this issue, let’s increase the
text-size of the paragraph from
18sp. This will increase the apparent contrast of the text against its background.
The TextView for
about_plaid.xml uses a style called
TextAppearance.About. To change the text size from
18sp, edit this section of
You can see a sample diff for this step at github.com/rsheeter/plaid/commit/4dda25
Update the App Title
Next, we’ll change the title of our app by fetching a font programmatically. The title is currently set in Roboto with the OpenType “small caps” feature applied. We’ve also used extra ‘tracking’ to space out the letters.
(This detail is borrowed from a convention of book typography, where chapter titles are often printed in small caps along the tops of pages. To learn more about typography, check out the book Shaping Text by Jan Middendorp.)
Async fetch will fail because Toolbar isn’t a TextView, just as CutoutTextView is not. Also, Toolbar doesn’t implement the fontFamily property, so we can’t just set blocking to fix it.
Instead, let’s try fetching and assigning the font programmatically. In
FontsContractCompat (reference) to request the font by following these four steps.
1. We’ll need a thread to await arrival of the font. Declare a variable to hold it:
private Handler fontHandler;
2. Add a method to manage the font handling thread:
3. Add a method to apply a
Typeface (reference) to the Toolbar:
onCreate, launch an async fetch from the font provider:
Switch to Alegreya Sans SC Black
Reviewing the main page, notice that the title looks a little too thin. Like many serif typefaces, Alegreya’s highly modulated strokes lead to lower visual contrast, especially when when compared to the average sans-serif.
Luckily, Alegreya is a “super family” with both serif and sans varieties in a range of weights. Pairing these two fonts and using different weights can give structure to an interface, delineating UI from content. Let’s try Alegreya Sans Small Caps (SC.)
The small caps variant of Alegreya is inherently smaller, but we can correct for this by increasing its weight. Let’s try the Black (900) weight.
name=Alegreya Sans SC&weight=900
res/values/preloaded_fonts.xmlto add the new font:
4. Specify the new query in
Change Alegreya Black to Bold
Take another look at the title on the main page
The Black weight is a little too strong here, so let’s dial it down to Bold (700.)
alegreya_sans_sc_bold.xmland edit to change
name=Alegreya Sans SC&weight=700
HomeActivity.javaupdate the query:
You can see a sample diff for the final state of the app (using Alegreya Sans SC Bold) at commit ac55478. See how your project compares.
Update Dribble View
To get to the “dribble” view in the app, tap or click a card on the main screen. Again, let’s replace Roboto Mono Regular with Alegreya Black.
app/src/main/res/layout/dribbble_shot_title.xml, notice that the title and description are styled using
@style/TextAppearance.DribbbleShotDescription. Find these in
app/src/main/res/values/styles.xml (hint: Ctrl+Click.) Now change the font:
You can see a sample diff for this at commit 0e53b56.
Change Numeral Styles
There’s just one more thing to improve on the “dribble” view.
The “likes” and “views” buttons use what are called “old style” numerals. These are designed to blend in with lowercase latin letters in paragraphs of text. But on their own, old style numerals look out of place because their descenders sometimes hang below the baseline of the other text.
Instead, let’s use the
lnum feature. This tells the app to use “lining” numerals, which are more familiar looking because they are designed to be the same height as capital letters. (Learn more from our friends at Typekit)
app/src/main/res/layout/dribbble_shot_description.xml we can see that the “likes” and “views” counters are styled by
app/src/main/res/values/styles.xml (hint: Ctrl+Click.)
Now add an instruction to use lining numbers for these counters:
You can see a sample diff for this at commit 4dda25.
After applying these simple changes, my fork of the Plaid app now has more striking and functional typography drawn from Google’s library of free, open-source fonts. With Android’s new Downloadable Fonts feature, you can use anything in the Google Fonts directory to customize typography in your app. As you’ve seen in this tutorial, just a few changes can make a real difference in legibility and user experience. We’re excited to see what you do!