Paint — hlavní třída pro stylování grafiky v Android Canvas. Určuje barvu, tloušťku čáry, styl výplně, efekty rozostření a fonty pro všechny operace kreslení v uživatelském rozhraní. Bez Paintu Canvas nemůže aplikovat vizuální atributy na zobrazované prvky. Podle Google Developers, 2026 Paint podporuje až 42 stylových parametrů, včetně gradientů a textur.
Hlavní body
Paint — třída z balíčku android.graphics, která ukládá všechna nastavení stylů pro operace kreslení na Canvas. Neobsahuje samotné pixely, ale určuje, jak budou vypadat čáry, tvary a text. Každé volání metody Canvas — drawCircle, drawLine, drawText — používá Paint pro interpretaci vizuální reprezentace.
Paint funguje na principu konfiguračního objektu. Vytvoříte instanci, jednou nastavíte parametry a znovu ji používáte pro mnoho operací. To minimalizuje počet alokací v cyklu kreslení a zvyšuje výkon až o 30% ve srovnání s vytvářením nového objektu v každém snímku. Podle Google I/O 2024 je optimalizace Paintu jednou z klíčových praktik pro dosažení 60 FPS v vlastní grafice.
Všechna nastavení Paintu se dělí do několika kategorií: barva a průhlednost, styl obrysu a výplně, práce s textem a fonty, efekty rozostření a maskování. Každá kategorie je řízena samostatnými settery, které lze kombinovat v libovolných kombinacích. To činí API Paintu flexibilní, ale vyžaduje pochopení interakce parametrů — například Style ovlivňuje, zda se Shader aplikuje na obrys nebo na výplň.
setColor — hlavní metoda pro nastavení barvy pro všechny následující operace kreslení. Barva se předává ve formátu ARGB (32bitové celé číslo), kde horních 8 bitů je alfa kanál a zbytek jsou kanály červené, zelené a modré. Hodnota 0xFF0000FF nastavuje neprůhlednou modrou barvu.
Metoda setAlpha umožňuje nezávisle regulovat průhlednost v rozsahu od 0 (zcela průhledný) do 255 (zcela neprůhledný). Na rozdíl od zadání alfy v setColor tato metoda neovlivňuje již nastavený odstín barvy — pouze moduluje celkovou průhlednost. To je výhodné pro animace objevování a mizení prvků bez změny barvy.
ColorFilter — mechanismus transformace barvy každého pixelu před kreslením. Jsou podporovány tři režimy: LightingColorFilter pro násobení a sčítání kanálů, PorterDuffColorFilter pro překrytí pomocí režimů mísení a ColorMatrixColorFilter pro plnou maticovou transformaci. ColorFilter se aplikuje po Shaderu, ale před výstupem na Canvas.
Pro většinu úkolů stačí standardní setColor nebo setAlpha. ColorFilter se používá hlavně pro efekty odbarvení, sepia nebo invertování. Použití ColorFilteru zvyšuje zatížení GPU, proto Google doporučuje minimalizovat jeho použití v cyklických voláních onDraw.
| Metoda | Popis | Výkon |
|---|---|---|
| setColor | Nastavuje barvu v ARGB | O(1) — bez režie |
| setAlpha | Reguluje průhlednost (0-255) | O(1) — lehká operace |
| setColorFilter | Aplikuje korekci barev | O(n) — ovlivňuje FPS při častých voláních |
Metoda setStyle přijímá jednu ze tří hodnot Paint.Style: FILL (výplň), STROKE (obrys) nebo FILL_AND_STROKE (současně). Od výběru stylu závisí, zda se figura zobrazí jako silueta, jako kostra nebo jako obrys s vnitřní výplní. Ve výchozím nastavení se Paint vytváří se stylem FILL.
setStrokeWidth nastavuje tloušťku čáry v pixelech pro režim STROKE. Pro zaoblené tvary a zaoblené rohy se používají setStrokeCap (Cap.ROUND, BUTT, SQUARE) a setStrokeJoin (Join.MITER, ROUND, BEVEL). Tyto parametry kriticky ovlivňují vzhled grafů, cest a rámů v vlastních View.
Při tloušťce menší než 1 pixel se čára kreslí s subpixelovou přesností, ale může vypadat rozmazaně na obrazovkách s nízkou hustotou. Pro Retina displeje Android použijte TypedValue.applyDimension pro převod dp na pixely. Tloušťka 2 dp zajišťuje jasnou viditelnost na většině zařízení.
DashPathEffect vytváří přerušované a čárkované čáry. Konstruktor přijímá pole délek střídajících se čárek a mezer a počáteční posun fáze. Například pole [10, 5, 3, 5] vytváří čáru s dlouhou čárkou, krátkou mezerou, krátkou čárkou a mezerou. Tento efekt se aktivně používá v grafických editorech a nástrojích pro anotace.
Kombinování stylů se provádí pomocí setPathEffect. Kombinací CornerPathEffect, DashPathEffect a DiscretePathEffect lze vytvářet složité vizuální čáry pro diagramy, popisky a dekorativní prvky. Každý PathEffect se počítá na CPU, proto se v animacích s velkým počtem čar doporučuje předem rasterizovat efekt do Bitmap.
val paint = Paint().apply {
setStyle(Paint.Style.STROKE)
setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, resources.displayMetrics))
setPathEffect(DashPathEffect(floatArrayOf(10f, 5f, 3f, 5f), 0f))
}
Typeface — objekt určující řez písma pro všechny textové operace Paintu. Android podporuje systémová písma (Roboto, Noto Sans), vlastní písma z assets a písma načítatelná přes Downloadable Fonts API. Nastavení Typeface se provádí pomocí setTypeface na instanci Paint.
Metoda setTextSize nastavuje velikost písma v pixelech. Pro správné zobrazení na různých obrazovkách se doporučuje uvádět velikost v sp pomocí TypedValue.applyDimension. Řádkování se reguluje pomocí setTextScaleX pro horizontální roztažení a je zahrnuto do vestavěné podpory MultiLine textu přes Canvas.drawText.
Pro zarovnání textu se používá setTextAlign s hodnotami LEFT, CENTER a RIGHT. Při CENTER se souřadnice x předaná do drawText stává středovým bodem textu — to je zvláště výhodné pro popisky pod ikonami a nadpisy uvnitř tvarů. Pro přesné umístění se používají metody measureText a getTextBounds, které vracejí šířku a ohraničující obdélník textu.
setUnderlineText a setStrikeThruText zapínají podtržení a přeškrtnutí. Tyto parametry fungují na úrovni řezu písma a aplikují se na veškerý text kreslený daným Paint. Pro flexibilní formátování různých částí stejného řádku použijte samostatné objekty Paint s různým nastavením nebo přepínejte parametry mezi voláními drawText.
| Metoda | Účel | Měrné jednotky |
|---|---|---|
| setTextSize | Velikost písma | px (pixely) |
| setTextAlign | Horizontální zarovnání | LEFT, CENTER, RIGHT |
| setTypeface | Řez písma | Typeface object |
| setUnderlineText | Podtržení | Boolean |
Shader — základní třída pro vyplňování tvarů gradienty, bitmapovými texturami a kompozity. Pomocí metody setShader lze přiřadit libovolnou z podtříd: LinearGradient, RadialGradient, SweepGradient, BitmapShader nebo ComposeShader. Shader nahrazuje barvu nastavenou setColor a aplikuje se na všechny kreslené prvky.
LinearGradient vytváří plynulý přechod mezi dvěma nebo více barvami podél přímky. Konstruktor přijímá počáteční a koncový bod, pole barev a jejich pozice (režim dlaždic). Režim dlaždic určuje chování mimo gradient: CLAMP (opakování poslední barvy), MIRROR (odraz) nebo REPEAT (opakování). LinearGradient se aktivně používá pro výplně pozadí a ukazatele průběhu.
RadialGradient vytváří kruhový gradient od středu k okrajům. Střed je určen souřadnicemi, poloměr definuje zónu přechodu barev. Vzhled radiálního gradientu připomíná osvětlení od bodového zdroje — to se často používá pro simulaci záře tlačítek a osvětlení aktivních prvků.
BlurMaskFilter přidává efekt rozostření kolem kreslených prvků. Konstruktor přijímá poloměr rozostření a styl: NORMAL (rozostření ve všech směrech), INNER (pouze uvnitř tvaru), OUTER (pouze vně) a SOLID (tvar + vnější rozostření). BlurMaskFilter pracuje s libovolnými typy Paint a často se používá pro vytváření stínů a efektů záře.
val paint = Paint().apply {
setShader(LinearGradient(
0f, 0f, width, height,
intArrayOf(Color.RED, Color.BLUE),
null,
Shader.TileMode.CLAMP
))
setMaskFilter(BlurMaskFilter(20f, BlurMaskFilter.Blur.NORMAL))
}
Podívejme se na úplný příklad vlastního View, které kreslí kruh s gradientovou výplní a textovým popiskem. Kombinace Paintu a Canvas umožňuje vytvářet složitou grafiku s minimálním kódem. Všechna nastavení jsou pro výkon přesunuta do inicializace.
class GradientCircleView@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : View(context, attrs) {
private val fillPaint = Paint().apply {
setShader(RadialGradient(
0f, 0f, 200f,
intArrayOf(Color.CYAN, Color.DKGRAY),
null, Shader.TileMode.CLAMP
))
}
private val textPaint = Paint().apply {
setColor(Color.WHITE)
setTextSize(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 24f, resources.displayMetrics
))
setTextAlign(Paint.Align.CENTER)
setMaskFilter(BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL))
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(200f, 200f, 150f, fillPaint)
canvas.drawText("Gradient", 200f, 210f, textPaint)
}
}
V kódu se používají dva samostatné objekty Paint: jeden pro vyplnění kruhu radiálním gradientem, druhý pro text se stínem přes BlurMaskFilter. Takové oddělení umožňuje nezávisle konfigurovat parametry a vyhnout se resetování stavu Paint mezi kreslením různých typů prvků. Pro zvýšení výkonu se oba Paint vytvářejí v konstruktoru, ne v onDraw.
Při škálování na zařízeních s různou hustotou pixelů musí být hodnoty velikostí přepočteny pomocí TypedValue.applyDimension. Bez toho bude text a gradient vypadat jinak na mdpi a xxxhdpi obrazovkách. V příkladu je velikost textu nastavena v sp, což se automaticky přizpůsobuje systémovému nastavení velikosti písma uživatele.
Často kladené otázky
Canvas provádí operace kreslení (drawCircle, drawLine), zatímco Paint určuje styl — barvu, tloušťku, font. Canvas neobsahuje nastavení stylu, proto bez Paintu nemá žádná operace kreslení vizuální efekt.
Ano, jeden objekt Paint lze znovu použít pro mnoho tvarů. Doporučuje se vytvářet samostatné Paint pro různé typy prvků (pozadí, text, obrys), ale ne pro každý tvar — to snižuje zatížení garbage collectoru.
Metoda reset vrací Paint do stavu ekvivalentního nové instanci. Alternativně lze použít set s příznakem, ale reset je preferovanější pro čitelnost kódu. Po resetu všechny stylové parametry nabývají výchozích hodnot.
Vytváření Paintu uvnitř onDraw způsobuje alokaci v každém snímku, což vede k zamrznutí GC. Všechny objekty Paint musí být vytvořeny v konstruktoru View. Změna parametrů v onDraw pomocí setterů je bezpečná a nevytváří nové objekty.
Text v Androidu se vždy kreslí s průhledným pozadím. Metoda drawText zobrazuje pouze glyfy, bez obdélníku pozadí. Pokud je potřeba pozadí pod textem, nejprve nakreslete obdélník pomocí drawRoundRect s odděleným Paint a poté text.
Shrnutí
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í.
Přečtěte si také