Custom fonts in Android
I've been playing with Android since late December (2011). Its been fun. I've been meaning to document some things I've picked up, but I've been pretty busy hacking away. Time to write a few things down before I forget!
In my - admittedly limited - experience, Android devices typically come pre-installed with just the one font family. Before Ice-Cream Sandwich that font was Droid. In Ice-Cream Sandwich its Roboto.
If you want to use other fonts in your app, you must package them as assets. I believe Android has supported true-type fonts since the beginning, but now also supports open-type fonts (since 1.6). I always use true-type fonts anyway.
To bundle the font, simply place the .tff file in your project's assets directory. Here's how you load the font in your Activity
code:
Typeface t = Typeface.createFromAsset(getAssets(), "my-font.ttf");
If you want to reference the font from xml markup you're in for a frustrating time. If you do want to take that path, check out this handy StackOverflow post.
If, like me, you prefer to set the font programmatically to the necessary views, you can call setTypeface(Typeface)
on TextView
's and EditText
's.
In some of my layouts (for example "help" screens) I have many TextView
's interspersed with ImageView
's. To make life a bit easier I use the following utility method to set the font on all TextView
's in the view hierarchy:
public static void setFontForAllTextViewsInHierarchy(
ViewGroup aViewGroup, Typeface aFont) {
for (int i=0; i<aViewGroup.getChildCount(); i++) {
View _v = aViewGroup.getChildAt(i);
if (_v instanceof TextView) {
((TextView) _v).setTypeface(aFont);
} else if (_v instanceof ViewGroup) {
setFontForAllTextViewsInHierarchy((ViewGroup) _v, aFont);
}
}
}
Using this utility method is as simple as finding ViewGroup
whose descendants need a font change, then invoking the method with that ViewGroup
:
// somewhere in an Activity..
Typeface font = Typeface.createFromAsset(getAssets(), "my-font.ttf");
ViewGroup vg = (ViewGroup) findViewById(R.id.myViewGroup);
Utils.setFontForAllTextViewsInHierarchy(vg, font);
I worried at first that this would cause a noticeable re-draw where you first see the system font, then it flashes over to the custom font. Since I tend to set my fonts in my Activity
's onCreate
method immediately following the call to setContentView
, my custom font is already specified before the first onDraw
invocation hits any of my View
's.