Typeface — co to je, typy písem a práce v Androidu

Autor: IT Sectr Publikováno: 2026-07-23 Doba čtení: 9 min

Typeface — je třída Android SDK z balíčku android.graphics, která reprezentuje řez písma a používá se pro přizpůsobení textu v TextView a dalších UI komponentách. Typeface určuje rodinu písma, jeho váhu (normal, bold) a styl (normal, italic). Podle Google Developers, Typeface podporuje načítání ze souborů TTF, OTF, XML písem a systémových zdrojů. Toto je centrální třída pro správu typografie v Android aplikacích.

Hlavní body

  • Typeface — Android třída pro reprezentaci řezu písma s rodinou a stylem
  • Vestavěné styly: Typeface.NORMAL, BOLD, ITALIC, BOLD_ITALIC
  • Písma se načítají z XML zdrojů, TTF/OTF souborů, assets nebo systémových složek
  • Android 8.0+ podporuje načítání písem přes XML zdroje v res/font
  • Typeface.create() vytváří instanci se zadanou rodinou a stylem

Co je Typeface?

Typeface — je Android třída, která zapouzdřuje informace o písmu: jeho rodinu (Roboto, Arial, Serif) a modifikátory stylu (tučnost, kurzíva). Na rozdíl od UIFont v iOS, Typeface neobsahuje informace o velikosti — velikost textu se nastavuje samostatně přes vlastnost textSize v TextView nebo TextStyle v Spannable. Typeface je zodpovědný pouze za řez a garnituru písma.

Třída je dostupná na všech úrovních API. Do Android 4.4 Typeface podporoval pouze omezenou sadu systémových písem: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF. Počínaje Android 8.0 (API 26) se objevila podpora načítání vlastních písem přes XML zdroje a Android 10 přidal podporu variabilních písem.

Vestavěné konstanty Typeface

Android poskytuje několik vestavěných instancí Typeface: Typeface.DEFAULT — systémové písmo Roboto (Material) nebo Noto (AOSP), DEFAULT_BOLD — tučná verze, MONOSPACE — neproporcionální písmo pro kód, SERIF — písmo s patkami (Noto Serif), SANS_SERIF — bezpatkové písmo (Noto Sans). Tyto konstanty jsou dostupné bez kontextu a nevyžadují oprávnění ke čtení souborů.

Typeface v systému

Systém Android používá Typeface pro vykreslování veškerého textu, včetně systémového UI, nadpisů, popisků a oznámení. Každá aplikace může přepsat výchozí písmo pomocí motivu (android:fontFamily) nebo programově přes setTypeface(). Typeface se aplikuje na všechny komponenty zděděné z TextView: tlačítka, EditText a vlastní zobrazení.

Vytvoření Typeface ze zdrojů

Android 8.0+ umožňuje přidávat písma do res/font a používat je přes XML zdroje. Soubor písma (TTF nebo OTF) se umístí do res/font, poté se vytvoří reference R.font.font_name. Typeface se načítá přes ResourcesCompat.getFont(context, R.font.font_name). Tento způsob je preferován, protože písmo je zkompilováno do APK a podporuje systémy rozvržení ProGuard.

Způsob přes zdroje také podporuje rodiny písem (font family) přes XML soubor v res/font: lze zadat několik souborů pro různé řezy (regular, bold, italic) a systém automaticky vybere správný soubor při volání setTypeface. To zjednodušuje typografii — stačí nastavit fontFamily v motivu a Android sám vybere vhodný soubor.

Vytvoření Typeface.create

Metoda Typeface.create(Typeface family, int style) vytváří instanci písma se zadanou rodinou a stylem. Pokud rodina již má požadovaný styl, vrátí se existující instance. Pokud styl neexistuje, Android ho syntetizuje — aplikuje falešné tučné písmo nebo umělou kurzívu na základní písmo.

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

Syntetizované pseudo-tučné písmo může vypadat nekvalitně na tenkých písmech. Pro lepší výsledek použijte soubor písma se skutečným bold řezem. Typeface.create() s neexistujícím stylem nevyhazuje výjimku, ale vrací nejbližší dostupnou variantu.

Typeface ze souboru a assets

Pro načtení Typeface z assets se používá Typeface.createFromAsset(assetManager, path). Písmo se umístí do adresáře src/main/assets/fonts/ a cesta se zadává relativně k assets. Tento způsob funguje na všech verzích Android, ale nepodporuje rodiny písem a vyžaduje zadání konkrétního souboru pro každý řez.

Metoda Typeface.createFromFile(File) načítá písmo z libovolného souboru v souborovém systému. To je užitečné pro písma stažená ze sítě nebo zkopírovaná do interního úložiště aplikace. createFromFile také nevyžaduje kontext, což je vhodné pro úlohy na pozadí, ale soubor musí být čitelný.

Načítání z assets s cache

Opakované načítání Typeface z assets přes createFromAsset může vést k vytváření duplicitních objektů. Každé volání createFromAsset načítá soubor znovu. Doporučuje se implementovat cache Typeface pomocí HashMap, kde klíčem je cesta k souboru a hodnotou je načtená instance. To je důležité zejména pro seznamy s různými typy písem.

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")
        }
    }
}
// Použití
val typeface = TypefaceCache.getTypeface(context, "Roboto-Bold.ttf")

Cache v paměti zaručuje, že se jedno písmo načítá pouze jednou za relaci aplikace. Při změně konfigurace (otočení obrazovky) cache zůstává, protože je v objektu companion. Pro čištění cache při nedostatku paměti použijte WeakHashMap nebo naslouchejte onTrimMemory.

Použití Typeface na TextView

Typeface se aplikuje na TextView pomocí metody setTypeface(Typeface tf) nebo setTypeface(Typeface tf, int style). Druhá varianta umožňuje změnit styl (bold/italic) vzhledem k aktuálnímu písmu. V XML se používá atribut android:fontFamily s odkazem na písmo nebo systémovou rodinu. Pro programové nastavení volání setTypeface(monospaceTypeface) nahradí písmo zadaným.

Typeface ovlivňuje celý text TextView. Pokud je v jednom řádku potřeba jiné písmo, použije se SpannableString s TypefaceSpan. TypefaceSpan přijímá Typeface nebo family a aplikuje se na rozsah znaků. To je jediný způsob, jak míchat písma v jednom TextView bez vnořených komponent.

TypefaceSpan pro část textu

Aplikujte TypefaceSpan pouze na část řetězce. Například hodnota proměnné v textu by měla být zobrazena neproporcionálním písmem a zbytek textu systémovým písmem. Vytvoří se SpannableString a na požadovaný rozsah se nastaví TypefaceSpan s MONOSPACE Typeface. Zbytek textu zůstává s původním písmem 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

Text „variableName“ se zobrazí neproporcionálním písmem modré barvy a slovo „Kod:“ zůstane systémovým písmem. TypefaceSpan lze kombinovat s libovolnými dalšími spany pro přesnou kontrolu nad každou částí textu.

Vlastní písma přes Typeface

Android podporuje několik formátů písem: TrueType (TTF), OpenType (OTF) a Web Open Font Format (WOFF2) od Android 10. TTF a OTF jsou hlavní formáty pro vlastní písma. XML písma (Font Family) nejsou samostatný formát, ale slouží jako popis, který soubor použít pro každý řez.

Pro použití vlastního písma přes res/font vytvořte XML soubor rodiny, kde zadáte cesty k souborům písma pro regular, bold a italic. Poté v motivu aplikace nastavte android:fontFamily="@font/custom_family". Všechny TextView používající tento motiv automaticky získají správný řez pro každý styl.

Načítání stažených písem

Pokud se písmo stahuje ze sítě, uložte jej do filesDir nebo cacheDir a načtěte přes Typeface.createFromFile. Po načtení aktualizujte Typeface v TextView. Pro asynchronní načítání použijte coroutine nebo DownloadManager a po dokončení pošlete do UI vlákna přes Handler. To je typický scénář pro aplikace s vlastní typografií načítanou na vyžádání.

kotlin
// Uložit soubor písma do interního úložiště
val fontFile = File(context.cacheDir, "downloaded-font.otf")
fontFile.outputStream().use { output ->
    // vstupní proud ze sítě
    inputStream.copyTo(output)
}
// Vytvořit Typeface ze souboru
val downloadedTypeface = Typeface.createFromFile(fontFile)
textView.typeface = downloadedTypeface

Před načtením zkontrolujte dostupnost souboru: pokud je soubor poškozený nebo neplatný, Typeface.createFromFile vyhodí RuntimeException. Doporučuje se obalit volání do try-catch a v případě chyby ponechat výchozí systémové písmo.

Typeface v Jetpack Compose

V Jetpack Compose se Typeface Android SDK nepoužívá přímo. Místo toho Compose poskytuje FontFamily a FontWeight pro typografii. FontFamily se načítá přes Font.Resource a Font.File. Systém typografie Compose se nastavuje přes MaterialTheme.typography, kde každému stylu (h1, body1, button) lze přiřadit vlastní FontFamily.

Pro načtení písma z resources Compose používá Font(R.font.font_name, weight, style). Písmo z assets se načítá přes Font(assetPath = "fonts/custom.otf", weight, style). Po definování písma se předá do Typography a poté se aplikuje přes MaterialTheme.typography.bodyLarge a podobné styly.

Konverze Typeface na písmo Compose

Pokud existuje hotový Typeface vytvořený přes Android SDK, lze jej použít v Compose přes TypefaceAdapter nebo vytvořením FontFamily na základě Typeface. Získejte Typeface z Typeface.create a předejte jej do FontFamily.Custom(listOf(Font(typeface))). Doporučuje se však používat nativní přístup s Font.Resource, protože je lépe optimalizovaný pro Compose.

Výkon a cache

Načítání písem ze souborů je potenciálně nákladná operace. Každé volání Typeface.createFromAsset nebo Typeface.createFromFile čte soubor z disku, parsuje jej a vytváří objekt Typeface. Pro písma o velikosti 1-2 MB to trvá 10-50 ms při studeném startu. Cache Typeface je povinná praxe pro aplikace s vlastními písmy.

Android SDK neukládá do cache písma vytvořená přes createFromAsset nebo createFromFile. Na rozdíl od systémových písem, která jsou přednačtena v procesu Zygote, vlastní písma se načítají při každém přístupu. Doporučuje se používat LruCache nebo ConcurrentHashMap s klíčem z identifikátoru písma. Velikost cache — 10-20 instancí, což pokrývá typickou sadu písem aplikace.

Optimalizace přes Font Family (API 26+)

Android 8.0+ optimalizuje načítání písem přes XML Font Family. Při zadání android:fontFamily="@font/my_family" v XML rozvržení Android načítá písmo líně — pouze když se komponenta stane viditelnou. Systém také ukládá do cache písma načtená přes ResourcesCompat.getFont() v globální cache procesu. To činí způsob přes zdroje nejvýkonnějším.

Typeface v RecyclerView

Při použití Typeface v adaptérech RecyclerView je důležité nenačítat písmo v metodě onBindViewHolder. Zavolejte načtení jednou při vytváření adaptéru nebo použijte ViewHolder s přednačteným Typeface. Pokud každá položka seznamu vyžaduje jedinečné písmo, implementujte cache přes WeakHashMap a čistěte ji při rolování mimo viditelné pozice pro úsporu paměti.

Často kladené otázky

Jaký je rozdíl mezi Typeface a FontFamily v Androidu?

Typeface — je konkrétní instance písma pro programové použití. FontFamily — XML zdroj popisující skupinu souborů písma pro různé řezy (regular, bold, italic). Za běhu se FontFamily převede na Typeface přes ResourcesCompat.getFont. Typeface lze vytvořit přímo ze souboru, bez použití FontFamily.

Jak načíst Typeface bez kontextu?

Použijte Typeface.createFromFile(File) nebo Typeface.DEFAULT. Tyto metody nevyžadují kontext, protože pracují se souborovým systémem nebo vestavěnými konstantami. Pro načítání z assets nebo zdrojů je kontext povinný, protože je potřeba přístup k AssetManager a zdrojům aplikace.

Lze Typeface použít v WebView?

Ne, WebView používá CSS vlastnost font-family pro zadávání písem. Pro použití vlastního písma v WebView umístěte soubor písma do assets a zadejte jej přes @font-face v CSS. Typeface Android SDK funguje pouze s nativními UI komponentami (TextView a jeho potomky).

Podporuje Typeface variabilní písma?

Ano, od Android 10 (API 29). Variabilní písma se načítají přes ResourcesCompat.getFont nebo Typeface.createFromFile. Pro nastavení os variability (weight, width) se používá FontStyle v Compose nebo XML atributy. Programová změna osy je možná pouze přes nízkoúrovňové API Skia.

Proč setTypeface nefunguje pro některá písma?

Nejčastější příčiny: soubor písma chybí v projektu, je zadán nesprávný název souboru, písmo je poškozené nebo se používá syntetizovaný styl, který v souboru neexistuje. Zkontrolujte, zda byl soubor přidán do res/font nebo assets a zda je jeho název uveden bez přípony v případě způsobu přes zdroje.

Shrnutí

  • Typeface — Android třída pro reprezentaci písma s rodinou a stylem řezu
  • Vestavěné konstanty: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF
  • Načítání přes ResourcesCompat.getFont, Typeface.createFromAsset, createFromFile
  • XML Font Family (API 26+) — preferovaný způsob pro vlastní písma
  • TypefaceSpan umožňuje použít písmo na část textu přes SpannableString
  • Cache Typeface je povinná — použijte HashMap nebo LruCache
  • V Compose používejte FontFamily a FontWeight místo Typeface Android SDK

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také