[android] How to Set a Custom Font in the ActionBar Title?

6 Answers

You can do this using a custom TypefaceSpan class. It's superior to the customView approach indicated above because it doesn't break when using other Action Bar elements like expanding action views.

The use of such a class would look something like this:

SpannableString s = new SpannableString("My Title");
s.setSpan(new TypefaceSpan(this, "MyTypeface.otf"), 0, s.length(),

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

The custom TypefaceSpan class is passed your Activity context and the name of a typeface in your assets/fonts directory. It loads the file and caches a new Typeface instance in memory. The complete implementation of TypefaceSpan is surprisingly simple:

 * Style a {@link Spannable} with a custom {@link Typeface}.
 * @author Tristan Waddington
public class TypefaceSpan extends MetricAffectingSpan {
      /** An <code>LruCache</code> for previously loaded typefaces. */
    private static LruCache<String, Typeface> sTypefaceCache =
            new LruCache<String, Typeface>(12);

    private Typeface mTypeface;

     * Load the {@link Typeface} and apply to a {@link Spannable}.
    public TypefaceSpan(Context context, String typefaceName) {
        mTypeface = sTypefaceCache.get(typefaceName);

        if (mTypeface == null) {
            mTypeface = Typeface.createFromAsset(context.getApplicationContext()
                    .getAssets(), String.format("fonts/%s", typefaceName));

            // Cache the loaded Typeface
            sTypefaceCache.put(typefaceName, mTypeface);

    public void updateMeasureState(TextPaint p) {

        // Note: This flag is required for proper typeface rendering
        p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);

    public void updateDrawState(TextPaint tp) {

        // Note: This flag is required for proper typeface rendering
        tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);

Simply copy the above class into your project and implement it in your activity's onCreate method as shown above.


How (if possible) could I set a custom font in a ActionBar title text(only - not the tab text) with a font in my assets folder? I don't want to use the android:logo option.

I just did the following inside the onCreate() function:

TypefaceSpan typefaceSpan = new TypefaceSpan("font_to_be_used");
SpannableString str = new SpannableString("toolbar_text");
str.setSpan(typefaceSpan,0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

I am using the Support Libraries, if you are not using them I guess you should switch to getActionBar() instead of getSupportActionBar().

In Android Studio 3 you can add custom fonts following this instructions https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html and then use your newly added font in "font_to_be_used"

From Android Support Library v26 + Android Studio 3.0 onwards, this process has become easy as a flick!!

Follow these steps to change the font of Toolbar Title:

  1. Read Downloadable Fonts & select any font from the list (my recommendation) or load a custom font to res > font as per Fonts in XML
  2. In res > values > styles, paste the following (use your imagination here!)

    <style name="TitleBarTextAppearance" parent="android:TextAppearance">
        <item name="android:fontFamily">@font/your_desired_font</item>
        <item name="android:textSize">23sp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">@android:color/white</item>
  3. Insert a new line in your Toolbar properties app:titleTextAppearance="@style/TextAppearance.TabsFont" as shown below

  4. Enjoy Custom Actionbar Title font styling!!

The Calligraphy library let's you set a custom font through the app theme, which would also apply to the action bar.

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item>

<style name="AppTheme.Widget"/>

<style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView">
   <item name="fontPath">fonts/Roboto-ThinItalic.ttf</item>

All it takes to activate Calligraphy is attaching it to your Activity context:

protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(new CalligraphyContextWrapper(newBase));

The default custom attribute is fontPath, but you may provide your own custom attribute for the path by initializing it in your Application class with CalligraphyConfig.Builder. Usage of android:fontFamily has been discouraged.

Following code will work for all the versions. I did checked this in a device with gingerbread as well as on JellyBean device

 private void actionBarIdForAll()
        int titleId = 0;

            titleId = getResources().getIdentifier("action_bar_title", "id", "android");
          // This is the id is from your app's generated R class when ActionBarActivity is used for SupportActionBar

            titleId = R.id.action_bar_title;

            // Do whatever you want ? It will work for all the versions.

            // 1. Customize your fonts
            // 2. Infact, customize your whole title TextView

            TextView titleView = (TextView)findViewById(titleId);

To add to @Sam_D's answer, I had to do this to make it work:

this.setTitle("my title!");
TextView title = ((TextView)v.findViewById(R.id.title));
// in order to start strolling, it has to be focusable and focused

It seems like overkill - referencing v.findViewById(R.id.title)) twice - but that's the only way it would let me do it.


public void findAndSetFont(){
        getActionBar().setTitle("SOME TEST TEXT");
        scanForTextViewWithText(this,"SOME TEST TEXT",new SearchTextViewInterface(){

            public void found(TextView title) {


public static void scanForTextViewWithText(Activity activity,String searchText, SearchTextViewInterface searchTextViewInterface){
    if(activity == null|| searchText == null || searchTextViewInterface == null)
    View view = activity.findViewById(android.R.id.content).getRootView();
    searchForTextViewWithTitle(view, searchText, searchTextViewInterface);

private static void searchForTextViewWithTitle(View view, String searchText, SearchTextViewInterface searchTextViewInterface)
    if (view instanceof ViewGroup)
        ViewGroup g = (ViewGroup) view;
        int count = g.getChildCount();
        for (int i = 0; i < count; i++)
            searchForTextViewWithTitle(g.getChildAt(i), searchText, searchTextViewInterface);
    else if (view instanceof TextView)
        TextView textView = (TextView) view;
public interface SearchTextViewInterface {
    void found(TextView title);