Android
Custom Font
Android Development
Mobile App Design
UI/UX Design

Android - Using Custom Font

Master System Design with Codemia

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

Introduction

Using a custom font in Android is mostly straightforward now, but the best approach depends on whether you are working with modern font resources or older asset-based loading. In current Android projects, res/font plus fontFamily is usually the cleanest option because it works well with XML layouts, styles, and Material components.

The Modern Approach: res/font

The recommended pattern is to place .ttf or .otf files in the res/font directory and reference them from XML.

Suppose the font file is saved as res/font/brand_sans.ttf. Then you can use it in a layout like this:

xml
1<TextView
2    android:layout_width="wrap_content"
3    android:layout_height="wrap_content"
4    android:text="Hello"
5    android:fontFamily="@font/brand_sans" />

This is simple, readable, and easy to reuse across the UI.

You can also centralize the font in a style instead of repeating it on every view:

xml
1<style name="BrandText">
2    <item name="android:fontFamily">@font/brand_sans</item>
3    <item name="android:textSize">18sp</item>
4</style>

That makes maintenance easier when the app uses the same font in multiple places.

Setting the Font in Kotlin or Java

Sometimes the font must be applied programmatically, for example in a custom view or conditional theme logic. In that case, ResourcesCompat is the usual choice.

kotlin
1import androidx.core.content.res.ResourcesCompat
2
3val typeface = ResourcesCompat.getFont(this, R.font.brand_sans)
4textView.typeface = typeface

This works well when the font depends on runtime conditions or when XML configuration is not enough.

The Older Asset-Based Method

Older tutorials often place fonts under assets/fonts and load them with Typeface.createFromAsset. That still works, but it is usually not the best default in modern apps.

kotlin
val typeface = Typeface.createFromAsset(assets, "fonts/brand_sans.ttf")
textView.typeface = typeface

The asset-based approach is more manual. It lacks some of the convenience and resource integration that res/font provides, which is why newer Android code usually prefers font resources.

Still, if you maintain a legacy app or need backward-compatible asset handling, this method remains valid.

Use Font Families When Weight and Style Matter

If the design system includes multiple weights such as regular, medium, and bold, define a font family XML resource instead of treating each file as a separate unrelated font.

xml
1<font-family xmlns:android="http://schemas.android.com/apk/res/android">
2    <font
3        android:font="@font/brand_sans_regular"
4        android:fontStyle="normal"
5        android:fontWeight="400" />
6    <font
7        android:font="@font/brand_sans_bold"
8        android:fontStyle="normal"
9        android:fontWeight="700" />
10</font-family>

Then reference the family from your layout or theme. That gives Android enough information to pick the right weight when the view asks for bold text.

Performance and Consistency Considerations

Custom fonts are a UI feature, but they still affect app behavior. A few practical rules help:

  • keep the number of bundled font files reasonable
  • use styles or themes instead of manually setting fonts everywhere
  • test the font on different screen densities and languages
  • make sure fallback behavior is acceptable for characters the font does not support

The last point matters more than many teams expect. A beautiful font that lacks important glyph coverage can become a localization problem quickly.

Common Pitfalls

A common mistake is using the old asset-loading approach everywhere in a modern app even though res/font would be simpler and more maintainable.

Another mistake is forgetting to package all required weights and then expecting Android to synthesize perfect bold and italic variants automatically.

People also often hardcode the font on many individual views instead of placing it in styles or theme attributes. That makes later design changes painful.

Finally, not every custom font has broad Unicode coverage. Always check how it behaves with non-English text and special symbols.

Summary

  • In modern Android projects, put custom fonts in res/font and reference them with fontFamily.
  • Use ResourcesCompat.getFont when the font must be applied in code.
  • Asset-based loading still works, but it is usually a legacy approach.
  • Font family XML is the right choice when multiple weights or styles are involved.
  • Test glyph coverage and keep font usage centralized for easier maintenance.

Course illustration
Course illustration

All Rights Reserved.