Styling the Android Action Bar title using a custom typeface

Styling the Action Bar in Android can frequently seem difficult, if not impossible. It’s easy to do wrong and hard to do right. However, customizing the Action Bar title with a custom typeface is a surprisingly easy way to spruce up your app design.

There are several posts on Stack Overflow that recommend accomplishing this by leveraging the Action Bar’s custom view feature, or by getting a reference to the title TextView. These solutions are adequate but can lead to infuriating edge cases. We can do better.

You might have come across the TypefaceSpan class, which allows you to style a section of text in a TextView with a monospace or serif font. This is almost what we want to do, but we need to be able to provide our own Typeface instance.

Here’s what a custom TypefaceSpan might look like in use:

    SpannableString s = new SpannableString("My Title");
    s.setSpan(new TypefaceSpan(this, "MyTypeface.otf"), 0, s.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 
    // Update the action bar title with the TypefaceSpan instance
    ActionBar actionBar = getActionBar();
    actionBar.setTitle(s);

Notice that we simply create a SpannableString with our desired Action Bar title. We then create a new instance of our custom TypefaceSpan providing it with our Activity context and the typeface name as arguments (so it can load the typeface from our application’s assets directory). The span is set on the entire length of the title (... 0, s.length(), ...). Finally, we pass in the Spannable.SPAN_EXCLUSIVE_EXCLUSIVE flag, which simply indicates that the span should be removed if all of the spanned text is deleted. Here’s what the result might look like:

android_action_bar_typeface_bender

android_action_bar_typeface_cubano

android_action_bar_typeface_gotham

But what does the custom TypefaceSpan implementation look like? Well, it’s surprisingly simple. I’ve created an example you can use in your own apps. You can get it at gist.github.com/twaddington/b91341ea5615698b53b8. Simply copy this class into your application and use it like I’ve indicated above. You can even subclass the custom TypefaceSpan to add additional styles like colors or text shadows.

Fonts Shown

38 thoughts on “Styling the Android Action Bar title using a custom typeface

  1. I’m getting 05-30 22:25:42.406: E/AndroidRuntime(3323): at com.blah.blah.TypefaceSpan.(TypefaceSpan.java:18)
    It seems that LruCache is not working in ADT v22.0.0
    It was working before.

    • LruCache is part of the support library. ADT v22 made some changes with how Eclipse dependencies are managed. Make sure your libs folder is getting imported properly.

  2. Hi, I placed this in my App’s MainActivity and the Title initially showed the default font of the App, then it will auto refresh and end up showing the Custom font. Is there any particular reason why this is the case as the change of font from default to custom can be seen when the Activity loads.

    • That’s probably due to the window decor showing the Action Bar before your Activity class has loaded. When your application is starting cold Android will show the window decor (background) set by your Activity/Application theme. If your theme includes the Action Bar it will also be included with your Application icon and Activity title (set in the manifest). This will not include the custom font because your Activity code has not executed yet. You could potentially solve this by hiding the Action Bar in your Theme and showing it in your Activity’s onCreate method.

      • I´ve seen apps like Google+ with the action bat title text customized even in cold start. I would like to know how they achieve this.

    • You could call the `setColor` method of the `TextPaint`, however I’d suggest just setting the tex size and color via your Application or Activity theme since this is quite easy to do.

  3. Good article.
    But I tried this to set a custom Typeface on my ActionBar’s tabs but it doesn’t seem to work =(
    Any tips?

    Cheers!

    • This code should work with any TextView. However, the tab view may be overriding the TypefaceSpan with another style. You might need to subclass the view to fix this problem. I’d take a look at the view’s source code to see what it’s doing. If you can’t figure it out you should post on stackoverflow.com for further help.

  4. I’m new to android development. I’m I to assume that I put the path and name of my font where you have “MyTypeface” in my MainActivity or in “fonts/%s.otf” in the TypefaceSpan.java? I’ve tried both and when I run in the emulator I get a message: Unfortunately, myapp has stopped.

    • The first thing you need to do is copy your .otf font files to an “assets/fonts/” directory you’ve created in your project. The “assets” directory should be right next to your “res” directory. You then need to create a “TypefaceSpan” java file and copy the code from the gist into that file. You should not need to modify any of the code in the “TypefaceSpan” class. Finally, in your “Activity” class you need to copy and paste the “SpannableString” sample code from the post above into your “onCreate” method. Replace the “MyTypeface” string with whatever your font file is named. So, if your font file is “assets/fonts/Cubano.otf” you need to replace “MyTypeface” with “Cubano”. If you need additional help, I’d suggest posting on stackoverflow.com.

      • I’ve done everything as you have stated and I get the same message. I posted on SO and no answer there. I guess I’ll have to try another way or just have a boring title font. Why there is no easy way to change the font of the title is beyond me.

  5. Thank you very much for this.
    Although I’d like to point out (and also for future reference) that this does not work out of the box for Android Kitkat 4.4 (as tested on an actual device running 4.4.2 AOSP).

    At first I thought I had just overlooked something when getSupportActionBar().setTitle(mSpannableString) does run but my ActionBar displays no title at all; but when I tried my project on an older phone (Galaxy GT-i9000) running Jelly Bean, the fonts displayed as expected.
    Took me a while but I believe the reason is that in 4.4, MetricAffectingSpan only supports openTypeFaces.

    So just in case someone else encounters a problem, check if you are using a TrueTypeFont. If so, just convert it to OTF.

    Do note that TTF and any other font works for devices running pre-kitkat (<4.4)

    • Thanks for the feedback, but this is incorrect. I just verified that a true type font works just fine on my Nexus 5 running Android 4.4. You’re likely running into some other bug. It’s possible that some change in Android 4.4 is causing the font to not work properly, but it’s not just because it’s a true type font. Likely there is some other problem with the font file or the way you’re formatting your text.

      • Thanks for the feedback too. Unfortunately only have two physical devices so I could not test it out more. But you are probably correct that this is just a bug with my ROM.
        Is it ok if you can try it with this font?
        http://www.fonts2u.com/clementepdao-heavy.font
        * (I’m not exactly sure but I believe this font is installed by default on MAC?)

        It’s the font that I was referring to that was not working and I counter-checked it with the OTF http://www.bariol.com/

        After I run the TTF file thru http://www.freefontconverter.com/ to get an OTF version, the font displayed properly.

        • I can confirm that the font file you indicated does not work for me on a Nexus 5 running Android 4.4. I would suspect that the process of converting it from ttf to otf fixed some issue with the font file. My guess is that if you converted it back to ttf it would work properly, but I don’t have time to test this right now.

  6. Hey there, thanks for the article, incredibly concise and helpful compared to the answers on SO.

  7. copy and paste didnt work

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    day = (TextView)findViewById(R.id.date);
    ttime = (TextView)findViewById(R.id.track);

    Typeface myfont = Typeface.createFromAsset(getAssets(), “fonts/DAEMONES.TTF”);
    ttime.setTypeface(myfont);

    SpannableString s = new SpannableString(“Argue-Ment”);
    s.setSpan(new TypefaceSpan(“brakingbad.otf”), 0, s.length(),
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    // Update the action bar title with the TypefaceSpan instance
    ActionBar actionBar = getActionBar();
    actionBar.setTitle(s);

    • Looks like you may have a spelling error in your typeface filename. I’d suggest double-checking that. If that doesn’t solve the problem, try reaching out for help on stackoverflow.com.

  8. I’m just starting android app dev and I’d like to implement your class. I’m getting various errors in Eclipse though and was hoping you could alleviate some of my pain.

    After putting the java file in my src directory I implement the above snippet into my onCreate and receive this error.

    http://kiraambrose.com/themes/default/images/typefaceError.png

    Since I’m a bit of a Java noob and I’m assuming that if my .java file is in the /src directory I should be able to use it in my main activities file (which is also located in my src directory).

    What am I doing incorrectly? Thanks for your time.

    • At first glance either your `MainActivity` does not extend a base `Activity` or, more likely, you imported the wrong `TypefaceSpan` class. Make sure the imports at the top of your class reference the custom `TypefaceSpan` class and not the system one. The error is telling you that the constructor you’re trying to use to create the span does not exist.

      If you need more help I’d suggest posting on stackoverflow.com.

  9. Hi Tristan, thanks for this excellent tutorial. Is there any way that you have conceived to add a drop-shadow to the text used in the span? I will continue my attempts and if I figure it out, I will post here.

    Thanks,

    J

  10. HI Tristan,

    I’ve done everything as you have described but I get the error “native typeface cannot be made”.
    I’m testing on a samsung galaxy s2 plus running android 4.1.2. my font is opficio.ttf

    • That sounds like the system can’t find the font. Make sure it’s spelled correctly and in the right directory. If you’re still having trouble I’d suggest posting on Stack Overflow.

  11. TypefaceSpan(this, “MyTypeface.otf”)

    here TypefaceSpan() is not taking the “this” argument, that’s why not working.

  12. Hi Tristan,

    Thanks a lot, I had been looking for a way to do this and your solution is really a good approach to do it.

    Thanks!

  13. hi, i able to change my action bar title with following code but could I change the font for each tab?

    I have following code to set the tab title:
    actionBar.addTab(actionBar.newTab()
    .setText(mPagerAdapter.getPageTitle(i))
    .setTabListener(this));

    the .getPageTitle return as CharSequence

  14. Hi, thanks a lot for the great tutorial! It worked great for me!
    Can you tell me how can I make the action bar title’ style Italic ?
    I checked the Typeface class and the createFromAsset method that you are using doesn’t allow specify the style…and there is no setStyle method…
    Thank you!

  15. hi, I tried this:
    Typeface tf = Typeface.createFromAsset(getAssets(), “fonts/Quicksand-Bold.otf”);
    SpannableString s = new SpannableString(getResources().getString(R.string.app_name));
    s.setSpan(tf, 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    getSupportActionBar().setTitle(s);
    the result is that I didn’t received any error, it set the correct string in the action bar, but the font is still the standard font.
    I have to use getSupportActionBar for old android version compatibility (my minimum is api level 7). I tried on a Samsung with api level 8 and another Samsung with api level 10.
    On the contrary for a normal button the font is setted correctly:
    ((TextView)findViewById(R.id.button)).setTypeface(tf);
    thanks for any help

  16. Hi sirji,
    thnx for nice blog its work bt i also want to chang font size so plz help me
    thnx

    • Hi Girish

      [XML Way]
      use “android:textSize”
      !! Attention !!
      Don’t use quote symbols beside the font size. It’s 28sp, not “28sp” .

      @android:color/white
      28sp

      [Java Code]
      In TypefaceSpan.java code, add “p.setTextSize(fontSize);” in updateMeasureState(TextPaint p) method and “tp.setTextSize(fontSize)” in updateDrawState(TextPaint tp) method.

      The unit of fontSize is pixel. If you need to convert sp to pixel, try:

      public static float spToPixels(Context context, float sp) {
      float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
      return sp * scaledDensity;
      }

  17. It din’t work for me. When i used this code I got the following error:
    Unable to start activity ComponentInfo{…../.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.app.ActionBar.setTitle(java.lang.CharSequence)’ on a null object reference.

    The error was pointed on actionBar.setTitle(s);

    Please help me…

    Thanks in advance….

Comments are closed.