Custom Fonts on Android — Using Font Styles

In our last post, we've looked at an easy way to apply a custom font to all TextViews, without writing a single line of additional code for each instance. If you experimented with our guide, you might have noticed that some TextView parameters, like textSize, continue to work very well. In contrast, textStyle, which defines if it's a regular, bold or italic font style, does not work anymore. This post will show a way to integrate the textStyle feature into our custom font TextView.

Hint: since this blog post series got more extended along the way, we decided to add a Github repository with the entire code base and an example activity.

Custom Fonts on Android Series Overview


Adding Font Files

The first thing to do is adding the font files (preferably as .ttf file) to the project. You'll need one .ttf file for each style. Continuing our example from last week with Source Sans Pro, your assets folder now should look like this:

Assets Folder with Font Files for Each Style

The base for applying text styles to our custom font is done. Next, we'll look how to integrate the textStyle property.

Using the XML textStyle-Property

You've seen in the previous blog post how to setup a custom view for use in the XML layout files. In this blog post, we changed the package name from a code snippet of our eat foody project to an open source class in our tutorial repository. If you worked with Android before, nothing of the following code snippet should surprise you:

<io.futurestud.tutorials.customfont.CustomFontTextView  
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="12dp"
    android:text="http://futurestud.io/blog/"
    android:textSize="18sp"
    android:textStyle="bold"/>

The first five XML properties are standard and work without any customization. The last textStyle works on normal TextViews, but not if you apply a custom font. However, we prefer to continue to use the standard android:textStyle instead of a special customfont:textStyle or similar. There is a bit of code necessary, which we'll show in the next section.

Side note: if you are interested in the option of using customfont:textStyle, we'll use that method in the next blog post to change the font via XML.

Implementation of CustomFontTextView

We've the font files and know that we can continue to use the textStyle property. Lastly, we've to adjust our CustomFontTextView class to understand the textStyle parameter and apply to the correct font style.

The first challenge is to get the information, which was defined in textStyle. This happens with one line of code:

int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);  

attr are the attributes which are applied to the TextView with the second constructor parameter. We can use that object to get the XML property information with the getAttributeIntValue() function.

Let's take a look at the parameter. ANDROID_SCHEMA is the constant with the same value as you define it in the top level of your XML (xmlns:android="http://schemas.android.com/apk/res/android"). The second parameter is the property name; in our case textStyle. The last parameter defines the default value, if the property was not set.

We chose Typeface.NORMAL since that is the most appropriate value when taking a look at the used constants in the TextView class:

Constant Value
normal 0
bold 1
italic 2
bolditalic 3

If there is no font style defined, we default to the regular font style.

Now we learned what values the int textStyle can be set to. Let's take a look at a function, which takes this into consideration.

private void applyCustomFont(Context context, AttributeSet attrs) {  
    int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);

    Typeface customFont = selectTypeface(context, textStyle);
    setTypeface(customFont);
}

private Typeface selectTypeface(Context context, int textStyle) {  
    /*
    * information about the TextView textStyle:
    * http://developer.android.com/reference/android/R.styleable.html#TextView_textStyle
    */
    switch (textStyle) {
        case Typeface.BOLD: // bold
            return FontCache.getTypeface("SourceSansPro-Bold.ttf", context);

        case Typeface.ITALIC: // italic
            return FontCache.getTypeface("SourceSansPro-Italic.ttf", context);

        case Typeface.BOLD_ITALIC: // bold italic
            return FontCache.getTypeface("SourceSansPro-BoldItalic.ttf", context);

        case Typeface.NORMAL: // regular
        default:
            return FontCache.getTypeface("SourceSansPro-Regular.ttf", context);
    }
}

You'll see the difference to the code in our previous blog post. We now don't just apply a font, we load it depending on the textStyle parameter.

The entire class would now look like this:

public class CustomFontTextView extends TextView {

    public static final String ANDROID_SCHEMA = "http://schemas.android.com/apk/res/android";

    public CustomFontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        applyCustomFont(context, attrs);
    }

    public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        applyCustomFont(context, attrs);
    }

    private void applyCustomFont(Context context, AttributeSet attrs) {
        int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);

        Typeface customFont = selectTypeface(context, textStyle);
        setTypeface(customFont);
    }

    private Typeface selectTypeface(Context context, int textStyle) {
        /*
        * information about the TextView textStyle:
        * http://developer.android.com/reference/android/R.styleable.html#TextView_textStyle
        */
        switch (textStyle) {
            case Typeface.BOLD: // bold
                return FontCache.getTypeface("SourceSansPro-Bold.ttf", context);

            case Typeface.ITALIC: // italic
                return FontCache.getTypeface("SourceSansPro-Italic.ttf", context);

            case Typeface.BOLD_ITALIC: // bold italic
                return FontCache.getTypeface("SourceSansPro-BoldItalic.ttf", context);

            case Typeface.NORMAL: // regular
            default:
                return FontCache.getTypeface("SourceSansPro-Regular.ttf", context);
        }
    }

This should be everything you need to use the standard textStyle to apply different font styles to your custom fonts.

Reviewing the Results

Let's look at an example layout with the standard Roboto font and multiple custom fonts (in different styles):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="12dp"
        android:text="http://futurestud.io/blog/"
        android:textSize="18sp"/>

    <io.futurestud.tutorials.customfont.CustomFontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="12dp"
        android:text="http://futurestud.io/blog/"
        android:textSize="18sp"/>

    <io.futurestud.tutorials.customfont.CustomFontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="12dp"
        android:text="http://futurestud.io/blog/"
        android:textSize="18sp"
        android:textStyle="bold"/>

    <io.futurestud.tutorials.customfont.CustomFontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="12dp"
        android:text="http://futurestud.io/blog/"
        android:textSize="18sp"
        android:textStyle="italic"/>

</LinearLayout>  

The result is just as expected:

Fonts from top to bottom: Roboto, Source Sans Pro, Source Sans Pro Bold, Source Sans Pro Italic

Next Steps

In this blog post you've seen how to use the textStyle to apply different styles to your custom font. All you need is one CustomFontTextView implementation and everything else is straightforward in XML. In our next blog post in this series, we'll go one step further. We'll show you how you can even set the font via XML.

If you have questions, let us know in the comments or on twitter @futurestud_io!

Explore the Library

Find interesting tutorials and solutions for your problems.

Miscellaneous