RSS

Search Engine

Saturday, May 22, 2010

Fun with Fonts

Inevitably, you’ll get the question “hey, can we change this font?” when doing application development. The answer depends on what fonts come with the platform, whether you can add other fonts, and how to apply them to the widget or whatever needs the font change.

Android is no different. It comes with some fonts plus a means for adding new fonts. Though, as with any new environment, there are a few idiosyncrasies to deal with.

Android natively knows three fonts, by the shorthand names of “sans”, “serif”, and “monospace”. These fonts are actually the Droid series of fonts, created for the Open Handset Alliance by Ascender.

For those fonts, you can just reference them in your layout XML, if you choose, such as:

  1. xml version="1.0" encoding="utf-8"?>
  2. <TableLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:stretchColumns="1">
  7. <TableRow>
  8. <TextView
  9. android:text="sans:"
  10. android:layout_marginRight="4px"
  11. android:textSize="20sp"
  12. />
  13. <TextView
  14. android:id="@+id/sans"
  15. android:text="Hello, world!"
  16. android:typeface="sans"
  17. android:textSize="20sp"
  18. />
  19. TableRow>
  20. <TableRow>
  21. <TextView
  22. android:text="serif:"
  23. android:layout_marginRight="4px"
  24. android:textSize="20sp"
  25. />
  26. <TextView
  27. android:id="@+id/serif"
  28. android:text="Hello, world!"
  29. android:typeface="serif"
  30. android:textSize="20sp"
  31. />
  32. TableRow>
  33. <TableRow>
  34. <TextView
  35. android:text="monospace:"
  36. android:layout_marginRight="4px"
  37. android:textSize="20sp"
  38. />
  39. <TextView
  40. android:id="@+id/monospace"
  41. android:text="Hello, world!"
  42. android:typeface="monospace"
  43. android:textSize="20sp"
  44. />
  45. TableRow>
  46. <TableRow>
  47. <TextView
  48. android:text="Custom:"
  49. android:layout_marginRight="4px"
  50. android:textSize="20sp"
  51. />
  52. <TextView
  53. android:id="@+id/custom"
  54. android:text="Hello, world!"
  55. android:textSize="20sp"
  56. />
  57. TableRow>
  58. TableLayout>

This layout builds a table showing short samples of four fonts. Notice how the first three have the android:typeface attribute, whose value is one of the three built-in font faces (e.g., “sans”).

The three built-in fonts are very nice. However, it may be that a designer, or a manager, or a customer wants a different font than one of those three. Or perhaps you want to use a font for specialized purposes, such as a “dingbats” font instead of a series of PNG graphics.

The easiest way to accomplish this is to package the desired font(s) with your application. To do this, simply create an assets/ folder in the project root, and put your fonts (in TrueType, or TTF, form) in the assets. You might, for example, create assets/fonts/ and put your TTF files in there.

Then, you need to tell your widgets to use that font. Unfortunately, you can no longer use layout XML for this, since the XML does not know about any fonts you may have tucked away as an application asset. Instead, you need to make the change in Java code:

  1. public class FontSampler extends Activity {
  2. @Override
  3. public void onCreate(Bundle icicle) {
  4. super.onCreate(icicle);
  5. setContentView(R.layout.main);

  6. TextView tv=(TextView)findViewById(R.id.custom);
  7. Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf");

  8. tv.setTypeface(face);
  9. }
  10. }

Here, we grab the TextView for our “custom” sample, then create a Typeface object via the static createFromAsset() builder method. This takes the application’s AssetManager (from getAssets()) and a path within your assets/ directory to the font you want.

Then, it is just a matter of telling the TextView to setTypeface(), providing the Typeface you just created. In this case, we are using the Handmade Typewriter font.

The results?

Font Sampler

Note that Android does not seem to like all TrueType fonts. I spent a lot of time trying to figure out what I was doing wrong with this sample, before switching to a different font, and everything “just worked”. When Android dislikes a custom font, rather than raise an Exception, it seems to substitute Droid Sans (”sans”) quietly. So, if you try to use a different font and it does not seem to be working, it may be that the font in question is incompatible with Android, for whatever reason.

Also note that TrueType fonts can be rather pudgy, particularly if they support an extensive subset of the available Unicode characters. The Handmade Typewriter font used here runs over 70KB; the DejaVu free fonts can run upwards of 500KB apiece. Even compressed, these add bulk to your application, so be careful not to go overboard with custom fonts, lest your application take up too much room on your users’ phones.

0 comments:

Post a Comment