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:
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:
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!