How to set custom font in Android

How to set custom font in Android

Approach 1: Typeface

In android, you can define your own custom fonts for the strings in your application. You just need to download (fonts.google.com) the required font from the internet, and then place it in assets/fonts folder.

After putting fonts in the assets folder under fonts folder, you can access it in your java code through Typeface class. First, get the reference of the TextView in the code. Its syntax is given below

TextView tvTitle = (TextView)findViewById(R.id.tvTitle);

The next thing you need to do is to call static method of Typeface class createFromAsset() to get your custom font from assets. Its syntax is given below

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/font_name.ttf");

The last thing you need to do is to set this custom font object to your TextView Typeface property. You need to call setTypeface() method to do that. Its syntax is given below

tvTitle.setTypeface(tf);

So, let's create simple demo.

Create a new project and fill the required details.

Add a new folder named assets inside src/main/ folder so that we are going to have the src/main/assets directory. Then add a new folder named fonts inside src/main/assets folder. We are going to have the directory: src/main/assets/fonts and we are going to add a .ttf font file inside.

Open your activity_main.xml and create a simple TextView.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="70dip"
        android:layout_marginTop="30dip"
        android:text="Coffe + cake ?" />

</LinearLayout>

Now open your MainActivity class file and try following code. In the following code I'm importing font from assets folder and using TypeFace class for applying custom font on TextView.

 
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Font path
        String fontPath = "fonts/coffee.ttf";

        // Text view label
        TextView tvTitle = (TextView) findViewById(R.id.tvTitle);

        // Loading font face
        Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);

        // Applying font
        tvTitle.setTypeface(tf);
    }
}

Result

android_typeface.png

There is however one problem with this approach. Let's say you have font.ttf and font_bold.ttf. If your TextView has the bold text style, it will be ignored because you applied the normal (non-bold) font. The same issue applies for italic styles. You can read solution here.

Approach 2: Calligraphy

We can use Calligraphy to set custom font for TextView, Button, EditText from layout file.

First step is include the dependency to build.gradle.

 
dependencies {
    compile 'uk.co.chrisjenx:calligraphy:2.2.0'
}

Add a new folder named assets inside src/main/ folder so that we are going to have the src/main/assets directory. Then add a new folder named fonts inside src/main/assets folder. We are going to have the directory: src/main/assets/fonts and we are going to add a .ttf font file inside.

Wrap the Activity Context:

 
@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

Last step is add TextView, Button, EditText to layout file.

 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:ignore="MissingPrefix">

    <TextView
        android:id="@+id/tvFont2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="30dip"
        android:layout_marginTop="20dip"
        android:text="TERMINATOR"
        fontPath="fonts/terminator.ttf"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Default font"
        android:layout_marginTop="30dip"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Custom font"
        fontPath="fonts/coffee.ttf"/>

    <EditText
        android:layout_marginTop="30dip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Default font"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Default font"
        fontPath="fonts/coffee.ttf"
        />

</LinearLayout>

Result

android_calligraphy.png

Approach 3: Android O, using custom font resources

One of the new features in Android O is using Custom Font Resources.

Android O supports custom fonts via font resources. The magic lies in the app/res folder. Creating the font folder is easy. It is like every other resource like menu, values, drawable, etc. So right click the res folder and create a new fonts folder.

Now you’re ready to drop in your fonts. So go ahead and pick a font of your choice. Android O supports both .otf (OpenType) and .ttf (TrueType) font formats.

Keep in mind, that resource files should use lowercase alphabets and underscores.

Head over to your XML layout file. Let’s skip the layout design and go straight to using our fonts.

 
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fontFamily="@font/caffee_regular"/>

Here's simple TextView. All you need to use a font is one attribute, and you’re good to go.

 
android:fontFamily="@font/caffee_regular"

You can assign a font programmatically too. First fetch the font Typeface. Then set it to your TextView.

 
Typeface typeface = getResources().getFont(R.font.caffee_regular);
tvTitle.setTypeface(typeface);

Additionally, you can specify a basic font style too. i.e. bold, italic or a combination of the two.

 
tvTitle.setTypeface(typeface, Typeface.BOLD_ITALIC);

You can also add custom fonts to any styles you’ve created in your app:

 
<style name="headlineFont" parent="@android:style/TextAppearance.Small">
   <item name="android:fontFamily">@font/caffee_regular</item>
</style>

Creating a Font Family. Sometimes you may unzip a font folder and discover multiple versions of the same font, such as an italicized version, or fonts with varying weights and thicknesses.

If you’re using multiple versions of the same font, then you may want to group them together into a font family. A font family is essentially a dedicated XML file where you define each version of the font, along with its associated style and weight attributes.

To create a font family:

Make sure you’ve added all the font files to your project’s res/font folder. Right-click your project's res/font folder, and then select New > Font resource file. Give this file a name, and then click OK. Open this XML file and define all the different versions of this font, along with their style and weight attributes, for example:

 
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/caffee_regular" />

    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/caffee_italic" />

    <font
        android:fontStyle="bold"
        android:fontWeight="400"
        android:font="@font/caffee_bold" />
</font-family>

You can then reference any of the fonts in this family using the android:fontFamily attribute. For example:

 
android:fontFamily="@font/doublefeature_bold"

Useful links

comments powered by Disqus