Android
Custom Fonts
XML Layouts
Mobile Development
User Interface

Custom fonts and XML layouts Android

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Custom fonts are one of the easiest ways to change the tone of an Android interface, but they only stay maintainable if they are wired into layouts cleanly. In modern Android projects, the right default is to treat fonts as resources, reference them from XML, and only use code when the typeface must change at runtime.

Put Fonts in res/font

The modern Android resource-based approach is to store font files in res/font. Once the file is there, Android generates a resource id for it, just like it does for strings and drawables.

For example:

  • 'res/font/inter_regular.ttf'
  • 'res/font/inter_bold.ttf'

become:

  • '@font/inter_regular'
  • '@font/inter_bold'

This is much cleaner than the older assets/fonts pattern because the resource is compile-time checked and works directly in XML.

Reference the Font in XML

If a TextView always uses the same font, keep that decision in the layout:

xml
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    android:layout_width="match_parent"
4    android:layout_height="match_parent"
5    android:orientation="vertical"
6    android:padding="24dp">
7
8    <TextView
9        android:id="@+id/titleText"
10        android:layout_width="wrap_content"
11        android:layout_height="wrap_content"
12        android:fontFamily="@font/inter_bold"
13        android:text="Profile"
14        android:textSize="24sp" />
15
16    <TextView
17        android:layout_width="wrap_content"
18        android:layout_height="wrap_content"
19        android:layout_marginTop="12dp"
20        android:fontFamily="@font/inter_regular"
21        android:text="Choose a display name"
22        android:textSize="16sp" />
23</LinearLayout>

This keeps typography visible in the XML where designers and developers expect to find it.

Use Font Family XML for Weights and Variants

If your design needs multiple weights from the same family, define a font family resource instead of scattering separate files across views.

xml
1<?xml version="1.0" encoding="utf-8"?>
2<font-family xmlns:android="http://schemas.android.com/apk/res/android">
3    <font
4        android:font="@font/inter_regular"
5        android:fontStyle="normal"
6        android:fontWeight="400" />
7    <font
8        android:font="@font/inter_bold"
9        android:fontStyle="normal"
10        android:fontWeight="700" />
11</font-family>

Now views can point at the family rather than individual files. This works better when you want Android to resolve normal versus bold usage from one logical family.

Prefer Styles for Repeated Layout Use

If several layouts use the same typography, define a style instead of repeating android:fontFamily everywhere.

xml
1<resources>
2    <style name="AppHeadline">
3        <item name="android:fontFamily">@font/inter_bold</item>
4        <item name="android:textSize">22sp</item>
5    </style>
6</resources>

Then apply it:

xml
1<TextView
2    android:layout_width="wrap_content"
3    android:layout_height="wrap_content"
4    style="@style/AppHeadline"
5    android:text="Featured item" />

This matters because font choices rarely travel alone. They usually come with size, weight, spacing, and color decisions.

Load Fonts in Code Only When the Choice Is Dynamic

If the font depends on runtime state such as a theme toggle or user preference, set it in code:

kotlin
1import android.os.Bundle
2import android.widget.TextView
3import androidx.appcompat.app.AppCompatActivity
4import androidx.core.content.res.ResourcesCompat
5
6class DetailActivity : AppCompatActivity() {
7    override fun onCreate(savedInstanceState: Bundle?) {
8        super.onCreate(savedInstanceState)
9        setContentView(R.layout.activity_detail)
10
11        val titleView = findViewById<TextView>(R.id.titleText)
12        val font = ResourcesCompat.getFont(this, R.font.inter_bold)
13        titleView.typeface = font
14    }
15}

That is still resource-based, which keeps the implementation safer than manually loading files from assets.

Fonts Change Layout Behavior

Typography is not separate from layout. A custom font changes width, line height, and readability. A layout that looked correct with the default system font can start clipping, wrapping awkwardly, or feeling visually cramped after the font changes.

For that reason, validate custom fonts in the real XML layouts that use them. In practice, that means:

  • avoid fixed heights for text-heavy views
  • prefer sp for text size
  • test long strings and translated strings
  • check accessibility font scaling

If the layout is rigid, the font will expose the weakness.

Common Pitfalls

  • Mixing the old assets/fonts pattern with the modern res/font resource pattern.
  • Using a custom font without bundling all the weights and styles the design expects.
  • Setting fonts in code when the choice is static and belongs in XML or styles.
  • Forgetting that custom fonts affect wrapping and spacing, not only appearance.
  • Choosing decorative fonts that hurt readability under localization or accessibility scaling.

Summary

  • Put bundled fonts in res/font so Android treats them as normal resources.
  • Use android:fontFamily in XML for static typography choices.
  • Define font-family resources and styles when several views share related type settings.
  • Load fonts in code only when the typeface is decided at runtime.
  • Always recheck the surrounding layout because typography changes sizing and flow.

Course illustration
Course illustration

All Rights Reserved.