Custom Fonts
There are times when using a custom font can improve your app. Some apps designed for reading provide additional font choices for users; other apps might use fonts specific to their brand. When deciding on whether to use an additional font, consider how it helps the user experience. Don’t include a font just because it’s popular or makes the app look different from others; include a font because a usability study has shown that your app is easier to read with the font or because your brand requires it and you want to avoid using images for custom text.
The Roboto font family was built specifically for Android and is the default font for Android 4.0 (Ice Cream Sandwich) and above. Whenever possible, it is the font you should use. You can download the font from the Google design site (http://www.google.com/design/spec/resources/roboto-noto-fonts.html), and it includes multiple variations. In addition to Roboto regular, there is a thin version, light version, medium version, black version, and condensed version (as well as bold and italic versions where applicable).
Because this font was built for Android specifically, it displays very well on a variety of densities and screen types. Many of the most commonly used fonts today were designed for print, which is a very different medium than an electronic display, so some of the fonts that look great on paper do not reproduce as well onscreen. In particular, if you are considering light or thin fonts, be sure to test them on medium- and high-density displays and test them against low-end devices with AMOLEDs (most modern AMOLEDs are reasonably comparable to LCDs, even besting them in some measures, but older and lower quality AMOLEDs like the ones used for the Nexus S have a different subpixel arrangement than a traditional LCD and on top of that have a low enough resolution that the subpixel arrangement can cause display issues for very thin items).
If you do decide to use an alternate font, you need to put it in a directory called assets within the root directory of your project. The easiest way to use a custom font in your app is to extend TextView to create your own class. Listing 10.10 shows an example.
Listing 10.10 A Custom TextView for Displaying a Font
public class TextViewRobotoThin extends TextView {
/**
* This is the name of the font file within the assets folder
*/
private static final String FONT_LOCATION = "roboto_thin.ttf";
private static Typeface sTypeface;
public TextViewRobotoThin(Context context) {
super(context);
setTypeface(getTypeface(context));
}
public TextViewRobotoThin(Context context, AttributeSet attrs) {
super(context, attrs);
setTypeface(getTypeface(context));
}
public TextViewRobotoThin(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setTypeface(getTypeface(context));
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TextViewRobotoThin(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setTypeface(getTypeface(context));
}
/**
* Returns the Typeface for Roboto Thin
*
* @param context Context to access the app's assets
* @return Typeface for Roboto Thin
*/
public static Typeface getTypeface(Context context) {
if (sTypeface == null) {
sTypeface = Typeface.createFromAsset(context.getAssets(), FONT_LOCATION);
}
returnsTypeface;
}
}
At the top of the class is a static string specifying the name of the font file. Each of the normal constructors calls setTypeface. A public static method called getTypeface() will create the Typeface from the font file in the assets directory, if it hasn’t already been created, and then return the Typeface. This is useful for times when you might access the Typeface for other uses (perhaps you do some custom drawing using this Typeface elsewhere). By having this public static method, anywhere in your code that needs this custom Typeface has one place to go, and you can just change the FONT_LOCATION if you need to change the font everywhere in the app.
You can now use this class anywhere you would use an ordinary TextView. For instance, you can replace the default “hello world” TextView with this in a new project. Figure 10.12 shows how this custom TextView looks on an actual device.
Figure 10.12 The custom TextView being displayed on a device