Typeface — що це, типи шрифтів та робота в Android

Автор: IT Sectr Опубліковано: 2026-07-23 Час читання: 9 хв

Typeface — це клас Android SDK з пакета android.graphics, який представляє накреслення шрифту і використовується для кастомізації тексту в TextView та інших компонентах інтерфейсу. Typeface визначає родину шрифту, його вагу (normal, bold) та стиль (normal, italic). За даними Google Developers, Typeface підтримує завантаження з файлів TTF, OTF, XML-шрифтів та системних ресурсів. Це центральний клас для керування типографікою в Android-додатках.

Головне

  • Typeface — клас Android для представлення накреслення шрифту з родиною та стилем
  • Вбудовані стилі: Typeface.NORMAL, BOLD, ITALIC, BOLD_ITALIC
  • Шрифти завантажуються з XML-ресурсів, TTF/OTF-файлів, assets або системних папок
  • Android 8.0+ підтримує завантаження шрифтів через XML-ресурси в res/font
  • Typeface.create() створює екземпляр із зазначеною родиною та стилем

Що таке Typeface?

Typeface — це клас Android, який інкапсулює інформацію про шрифт: його родину (Roboto, Arial, Serif) та модифікатори стилю (bold, italic). На відміну від UIFont в iOS, Typeface не містить інформації про розмір — розмір тексту задається окремо через властивість textSize в TextView або TextStyle в Spannable. Typeface відповідає лише за накреслення та гарнітуру шрифту.

Клас доступний на всіх рівнях API. До Android 4.4 Typeface підтримував лише обмежений набір системних шрифтів: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF. Починаючи з Android 8.0 (API 26), було додано підтримку завантаження кастомних шрифтів через XML-ресурси, а Android 10 додав підтримку варіативних шрифтів.

Вбудовані константи Typeface

Android надає кілька вбудованих екземплярів Typeface: Typeface.DEFAULT — системний шрифт Roboto (Material) або Noto (AOSP), DEFAULT_BOLD — жирна версія, MONOSPACE — моноширинний шрифт для коду, SERIF — шрифт з засічками (Noto Serif), SANS_SERIF — гротеск (Noto Sans). Ці константи доступні без контексту та не потребують дозволів на читання файлів.

Typeface в системі

Система Android використовує Typeface для відображення всього тексту, включаючи системний інтерфейс, заголовки, підписи та сповіщення. Кожен додаток може перевизначити типовий шрифт через тему (android:fontFamily) або програмно через setTypeface(). Typeface застосовується до всіх компонентів, успадкованих від TextView: кнопок, EditText та кастомних вюхів.

Створення Typeface з ресурсів

Android 8.0+ дозволяє додавати шрифти в res/font та використовувати їх через XML-ресурси. Файл шрифту (TTF або OTF) поміщується в res/font, після чого створюється посилання R.font.font_name. Typeface завантажується через ResourcesCompat.getFont(context, R.font.font_name). Цей спосіб кращий, оскільки шрифт компілюється в APK та підтримує системи збірки ProGuard.

Ресурсний спосіб також підтримує родини шрифтів через XML-файл в res/font: можна вказати кілька файлів для різних накреслень (regular, bold, italic) і система автоматично вибере потрібний файл при виклику setTypeface. Це спрощує типографіку — достатньо задати fontFamily в темі, і Android сам підбере підходячий файл.

Створення Typeface.create

Метод Typeface.create(Typeface family, int style) створює екземпляр шрифту із зазначеною родиною та стилем. Якщо родина вже має запитаний стиль, повертається існуючий екземпляр. Якщо стиль відсутній, Android синтезує його — застосовує псевдожирність або штучний курсив до базового шрифту.

kotlin
val boldTypeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD)
val italicTypeface = Typeface.create(Typeface.MONOSPACE, Typeface.ITALIC)
val customTypeface = ResourcesCompat.getFont(context, R.font.montserrat_regular)
textView.typeface = boldTypeface

Синтезований псевдожирний може виглядати неякісно на тонких шрифтах. Для кращого результату використовуйте файл шрифту з справжнім bold-накресленням. Typeface.create() з неіснуючим стилем не викидає виняток, а повертає найближчий доступний варіант.

Typeface з файлу та assets

Для завантаження Typeface з assets використовуйте Typeface.createFromAsset(assetManager, path). Шрифт поміщується в каталог src/main/assets/fonts/, а шлях вказується відносно assets. Цей спосіб працює на всіх версіях Android, але не підтримує родини шрифтів і вимагає вказівки конкретного файлу для кожного накреслення.

Метод Typeface.createFromFile(File) завантажує шрифт з довільного файлу в файловій системі. Це корисно для шрифтів, завантажених з мережі або скопійованих у внутрішнє сховище додатка. createFromFile також не потребує контексту, що зручно для фонових завдань, але файл повинен бути доступним для читання.

Завантаження з assets з кешуванням

Багаторазове завантаження Typeface з assets через createFromAsset може призводити до створення дублікативних об’єктів. Кожен виклик createFromAsset завантажує файл заново. Рекомендується реалізувати кеш Typeface через HashMap, де ключем є шлях до файлу, а значенням — завантажений екземпляр. Це особливо актуально для списків з різними типами шрифтів.

kotlin
object TypefaceCache {
    private val cache = mutableMapOf<String, Typeface>()
    fun getTypeface(context: Context, filename: String): Typeface {
        return cache.getOrPut(filename) {
            Typeface.createFromAsset(context.assets, "fonts/$filename")
        }
    }
}
// Usage
val typeface = TypefaceCache.getTypeface(context, "Roboto-Bold.ttf")

Кеш у пам’яті гарантує, що один шрифт завантажується тільки один раз за сесію додатка. При зміні конфігурації (поворот екрану) кеш зберігається, оскільки знаходиться в об’єкті companion. Для очищення кешу при нестачі пам’яті використовуйте WeakHashMap або прослуховуйте onTrimMemory.

Застосування Typeface до TextView

Typeface застосовується до TextView через метод setTypeface(Typeface tf) або setTypeface(Typeface tf, int style). Другий варіант дозволяє змінити стиль (bold/italic) відносно поточного шрифту. В XML використовується атрибут android:fontFamily з посиланням на шрифт або системну родину. Для програмного встановлення виклик setTypeface(monospaceTypeface) замінить шрифт на вказаний.

Typeface впливає на весь текст TextView. Якщо потрібен різний шрифт в одному рядку, використовуйте SpannableString з TypefaceSpan. TypefaceSpan приймає Typeface або родину і застосовується до діапазону символів. Це єдиний спосіб змішувати шрифти в межах одного TextView без вкладених компонентів.

TypefaceSpan для частини тексту

Застосуйте TypefaceSpan лише до частини рядка. Наприклад, значення змінної в тексті повинно бути моноширинним, а решта тексту — системним шрифтом. Створіть SpannableString та встановіть TypefaceSpan з MONOSPACE Typeface на потрібний діапазон. Решта тексту зберігає оригінальний шрифт TextView.

kotlin
val text = "Code: variableName"
val spannable = SpannableString(text)
spannable.setSpan(
    TypefaceSpan(Typeface.MONOSPACE),
    5, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
spannable.setSpan(
    ForegroundColorSpan(Color.BLUE),
    5, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannable

Текст «variableName» відобразиться моноширинним шрифтом синього кольору, а слово «Code:» залишиться системним шрифтом. TypefaceSpan можна комбінувати з будь-якими іншими спанами для точного контролю над кожною ділянкою тексту.

Кастомні шрифти через Typeface

Android підтримує кілька форматів шрифтів: TrueType (TTF), OpenType (OTF) та Web Open Font Format (WOFF2) починаючи з Android 10. TTF і OTF — основні формати для кастомних шрифтів. XML-шрифти (Font Family) не є окремим форматом, а слугують описом того, який файл використовувати для кожного накреслення.

Для використання кастомного шрифту через res/font створіть XML-файл родини, де вказуються шляхи до файлів шрифтів для regular, bold та italic. Потім у темі додатка вкажіть android:fontFamily="@font/custom_family". Усі екземпляри TextView, які використовують цю тему, автоматично отримають правильне накреслення для кожного стилю.

Завантаження завантажених шрифтів

Якщо шрифт завантажується з мережі, збережіть його в filesDir або cacheDir та завантажте через Typeface.createFromFile. Після завантаження оновіть Typeface в TextView. Для асинхронного завантаження використовуйте coroutine або DownloadManager, а після завершення постьте в UI-потік через Handler. Це типовий сценарій для додатків з кастомною типографікою, що завантажується на вимогу.

kotlin
// Save font file to internal storage
val fontFile = File(context.cacheDir, "downloaded-font.otf")
fontFile.outputStream().use { output ->
    // inputStream from network
    inputStream.copyTo(output)
}
// Create Typeface from file
val downloadedTypeface = Typeface.createFromFile(fontFile)
textView.typeface = downloadedTypeface

Перед завантаженням перевірте доступність файлу: якщо файл пошкоджений або недійсний, Typeface.createFromFile викидає RuntimeException. Рекомендується обертати виклик в try-catch і у разі помилки повертатися до типового системного шрифту.

Typeface в Jetpack Compose

В Jetpack Compose Typeface Android SDK не використовується безпосередньо. Натомість Compose надає FontFamily та FontWeight для типографіки. FontFamily завантажується через Font.Resource та Font.File. Система типографіки Compose визначається через MaterialTheme.typography, де кожному стилю (h1, body1, button) можна призначити кастомну FontFamily.

Для завантаження шрифту з ресурсів Compose використовує Font(R.font.font_name, weight, style). Шрифт з assets завантажується через Font(assetPath = "fonts/custom.otf", weight, style). Після визначення шрифту він передається в Typography, а потім застосовується через MaterialTheme.typography.bodyLarge та аналогічні стилі.

Конвертація Typeface в шрифт Compose

Якщо є готовий Typeface, створений через Android SDK, його можна використати в Compose через TypefaceAdapter або створивши FontFamily на основі Typeface. Отримайте Typeface з Typeface.create та передайте його в FontFamily.Custom(listOf(Font(typeface))). Однак рекомендується використовувати рідний підхід з Font.Resource, оскільки він краще оптимізований для Compose.

Продуктивність та кешування

Завантаження шрифтів з файлів — потенційно дорога операція. Кожен виклик Typeface.createFromAsset або Typeface.createFromFile читає файл з диска, парсить його та створює об’єкт Typeface. Для шрифтів розміром 1-2 МБ це займає 10-50 мс на холодному запуску. Кешування Typeface — обов’язкова практика для додатків з кастомними шрифтами.

Android SDK не кешує шрифти, створені через createFromAsset або createFromFile. На відміну від системних шрифтів, які попередньо завантажуються в процесі Zygote, кастомні шрифти завантажуються при кожному зверненні. Рекомендується використовувати LruCache або ConcurrentHashMap з ідентифікатором шрифту як ключем. Розмір кешу 10-20 екземплярів покриває типовий набір шрифтів додатка.

Оптимізація через Font Family (API 26+)

Android 8.0+ оптимізує завантаження шрифтів через XML Font Family. При вказівці android:fontFamily="@font/my_family" в XML-розмітці Android завантажує шрифт леніво — лише коли компонент стає видимим. Система також кешує шрифти, завантажені через ResourcesCompat.getFont(), у глобальному кеші процесів. Це робить ресурсний спосіб найбільш продуктивним.

Typeface в RecyclerView

При використанні Typeface в адаптерах RecyclerView важливо не завантажувати шрифт в методі onBindViewHolder. Викличіть завантаження один раз при створенні адаптера або використовуйте ViewHolder з попередньо завантаженим Typeface. Якщо кожен елемент списку потребує унікальний шрифт, реалізуйте кеш через WeakHashMap та очищайте його при прокрутці поза межі видимих позицій для економії пам’яті.

Часто задавані питання

Чим відрізняється Typeface від FontFamily в Android?

Typeface — це конкретний екземпляр шрифту для програмного використання. FontFamily — XML-ресурс, що описує групу файлів шрифту для різних накреслень (regular, bold, italic). В runtime FontFamily перетворюється в Typeface через ResourcesCompat.getFont. Typeface можна створити безпосередньо з файлу, минаючи FontFamily.

Як завантажити Typeface без контексту?

Використовуйте Typeface.createFromFile(File) або Typeface.DEFAULT. Ці методи не потребують контексту, оскільки працюють з файловою системою або вбудованими константами. Для завантаження з assets або ресурсів контекст обов’язковий, оскільки потрібен доступ до AssetManager та ресурсів додатка.

Чи можна використовувати Typeface в WebView?

Ні, WebView використовує CSS-властивість font-family для вказівки шрифтів. Щоб використати кастомний шрифт в WebView, помістіть файл шрифту в assets та вкажіть його через @font-face в CSS. Typeface Android SDK працює лише з нативними UI-компонентами (TextView та його нащадками).

Чи підтримує Typeface варіативні шрифти?

Так, починаючи з Android 10 (API 29). Варіативні шрифти завантажуються через ResourcesCompat.getFont або Typeface.createFromFile. Для налаштування осей варіативності (weight, width) використовуйте FontStyle в Compose або XML-атрибути. Програмна зміна осей можлива лише через низькорівневі API Skia.

Чому setTypeface не працює для деяких шрифтів?

Найчастіші причини: файл шрифту відсутній в проекті, неправильне ім’я файлу, шрифт пошкоджений або використовується синтезований стиль, якого немає в файлі. Перевірте, що файл додано в res/font або assets, і що його ім’я вказано без розширення у разі ресурсного способу.

Підсумки

  • Typeface — клас Android для представлення шрифту з родиною та стилем накреслення
  • Вбудовані константи: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF
  • Завантаження через ResourcesCompat.getFont, Typeface.createFromAsset, createFromFile
  • XML Font Family (API 26+) — прекращений спосіб для кастомних шрифтів
  • TypefaceSpan дозволяє застосувати шрифт до частини тексту через SpannableString
  • Кешування Typeface обов’язкове — використовуйте HashMap або LruCache
  • В Compose використовуйте FontFamily та FontWeight замість Typeface Android SDK

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також