Typeface — какво е, видове шрифтове и работа в Android

Автор: IT Sectr Публикувано: 2026-07-23 Време за четене: 9 мин

Typeface — е клас на Android SDK от пакета android.graphics, който представлява изгледа на шрифта и се използва за персонализиране на текст в TextView и други UI компоненти. 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) и стилови модификатори (удебеляване, курсив). За разлика от 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 за изобразяване на целия текст, включително системен UI, заглавия, етикети и известия. Всяко приложение може да презапише шрифта по подразбиране чрез тема (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.

Ресурсният начин поддържа също семейства шрифтове (font family) чрез 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")
        }
    }
}
// Употреба
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 или family и се прилага към диапазон от символи. Това е единственият начин за смесване на шрифтове в един 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“ ще се покаже с моноширинен шрифт в син цвят, а думата „Kod:“ ще остане със системен шрифт. TypefaceSpan може да се комбинира с всякакви други span-ове за прецизен контрол над всяка част от текста.

Персонализирани шрифтове чрез 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
// Запазване на файл с шрифт във вътрешно хранилище
val fontFile = File(context.cacheDir, "downloaded-font.otf")
fontFile.outputStream().use { output ->
    // входен поток от мрежа
    inputStream.copyTo(output)
}
// Създаване на Typeface от файл
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.

За зареждане на шрифт от resources 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 MB това отнема 10-50 ms при студен старт. Кеширането на 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). По време на изпълнение 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също