Saturday, April 9, 2011

Using Custom fonts on Android

I had to do this for a project that I am working on, and I felt that it wasn't possible to achieve this. Well, there are several examples on the internet regarding this and nothing seemed to be working for me. So, in this post, we will see how to use custom fonts for your application on Android.

Few things before we start off:
  • Not all fonts are compatible with Android
  • You need to package the ttf files with your apk
  • It's obviously a little bit of extra work
So for this example, we have a TextView and a Button with different fonts. To be able to use your custom font everywhere, ie, on all the TextView and Button widgets in your app, you will have to extend these classes to create your own TextView and Button classes. I have named them as MyTextView and MyButton. And then, I can use these buttons in my layout xml files, with the fully-qualified name of my custom classes.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.beanie.samples.customfont.MyTextView
        android:layout_marginTop="10dip" android:id="@+id/textView"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:text="@string/hello" android:textSize="20sp"></com.beanie.samples.customfont.MyTextView>

    <com.beanie.samples.customfont.MyButton
        android:layout_marginTop="10dip" android:id="@+id/textView"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:text="@string/hello" android:textSize="20sp"></com.beanie.samples.customfont.MyButton>
</LinearLayout>
In both these classes, we have a method called init() which is called from all the constructors. The method is just 3 line long.
        if (!isInEditMode()) {
                  Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/ds_digib.ttf");
                  setTypeface(tf);
        }
Simple!!! You might notice that there is an if condition. This is not required, but it does help when you are preparing your layouts on eclipse, and you need to keep checking if everything's fine. This method, isInEditMode() returns true while eclipses tries to render the view from the XML.

This is what the documentation says:
Indicates whether this View is currently in edit mode. A View is usually in edit mode when displayed within a developer tool. For instance, if this View is being drawn by a visual user interface builder, this method should return true. Subclasses should check the return value of this method to provide different behaviors if their normal behavior might interfere with the host environment. For instance: the class spawns a thread in its constructor, the drawing code relies on device-specific features, etc. This method is usually checked in the drawing code of custom widgets.
If you don't put this condition, the layout editor will complain about not being able to set the TypeFace. So, in the layout editor, you will see your TextView and Button widgets with the default font. But, when you run your app on an emulator or a device, you can see the goodness of your custom fonts.

The source code for the sample project can be found here. You can find 3 different fonts (ttf file) in the assets folder to play with.

19 comments:

  1. Hi thank you
    it workt perfect finnaly a good sample
    not like all the shit i found before

    ReplyDelete
  2. Unfortunately too much thing to do, if I want to use fonts in the whole application.

    For every single widget a custom widget must be created :(

    ReplyDelete
  3. @Mur Votema: Yeah, actually, it is.

    ReplyDelete
  4. is there any way to get the screen resolution during edit mode?
    i'm trying to set the fields of some custom views depending on it , and i wish to see the difference even on design mode.

    ReplyDelete
  5. It doesn't really makes sense, to get the screen resolution during edit mode. The screen can be of any resolution, depending in the device that your application is running on.

    ReplyDelete
  6. can you make a tutorial with sample code on how to create a widget with custom font plz ?

    ReplyDelete
  7. @ShengLong: You can find the source code with a working sample. The link is in the post. Here it goes again.

    Link to sample

    ReplyDelete
    Replies
    1. Really very good tutorial..and thank you very much!!!! But i tried using this to my android homescreen widget but its not coming.. As per my knowledge from the search i made they saying like widgets cant have their own fonts cause they dont run in their own process like app. They run in Homescreen's process. So if you know any way to do this in homescreen widget please let me know.
      Thanks.

      Delete
  8. Excellent example. To the point and emminently useful. Many thanks.

    ReplyDelete
  9. On Homescreen widgets, I haven't tried it yet. But I think it wouldn't work.

    ReplyDelete
  10. hei and thanks or the great example
    you mentioned: "You need to package the ttf files with your apk"
    so I wonder,
    Is there a way for a running android app to download a font and use it ?

    ReplyDelete
  11. Hi Kumar and thanks for the great work.

    you mentioned "You need to package the ttf files with your apk"
    is there a way for an app to download ttf file and use it while running ?

    ReplyDelete
  12. This is pretty useful stuff.. Thanks

    ReplyDelete
  13. Hi, this is a useful post. I just want to confirm if do we need to check for the licenses of these fonts before bundling them in our application?

    ReplyDelete
  14. //Code
    tf4 = Typeface.createFromAsset( getAssets(), "CN_1.TTC");
    cn1b.setTypeface(tf4);

    Tried with Japanese & chinese fonts not working any solution ?
    It always remains blank .. Tried many ttf & ttc fonts ..


    How to find which JP & CH fonts are working with droid ..?

    ReplyDelete
    Replies
    1. I tried with a Japanese font called kirieji.ttf and it worked fine.

      Delete
  15. Hi,

    If i want to support custom font in webview inside our app, it works fine till 4.0 but from 4.0 and higher its not working, any suggestions please this is very urgent requirement.

    ReplyDelete