Paint — de hoofdklasse voor het stylen van graphics in Android Canvas. Het bepaalt de kleur, lijn dikte, vulstijl, vervagingseffecten en lettertypen voor alle tekenbewerkingen in de gebruikersinterface. Zonder Paint kan Canvas geen visuele attributen toepassen op weergegeven elementen. Volgens Google Developers, 2026 ondersteunt Paint tot 42 stijlparameters, inclusief verloop en texturen.
Belangrijkste punten
Paint — een klasse uit het android.graphics-pakket die alle stijlinstellingen voor tekenbewerkingen op Canvas opslaat. Het bevat niet de pixels zelf, maar bepaalt hoe lijnen, vormen en tekst eruitzien. Elke aanroep van een Canvas-methode — drawCircle, drawLine, drawText — gebruikt Paint voor de interpretatie van de visuele weergave.
Paint werkt volgens het principe van een configuratieobject. Je maakt een instantie, stelt de parameters eenmaal in en hergebruikt deze voor meerdere bewerkingen. Dit minimaliseert het aantal allocatie in de tekenlus en verhoogt de prestaties met tot 30% in vergelijking met het maken van een nieuw object per frame. Volgens Google I/O 2024 is het optimaliseren van Paint een van de belangrijkste praktijken voor het bereiken van 60 FPS in aangepaste graphics.
Alle Paint-instellingen zijn onderverdeeld in verschillende categorieën: kleur en transparantie, lijn- en vulstijl, werken met tekst en lettertypen, vervagings- en maskereffecten. Elke categorie wordt beheerd door afzonderlijke setter-methoden die in elke combinatie kunnen worden gebruikt. Dit maakt de Paint API flexibel, maar vereist begrip van de interactie tussen parameters — bijvoorbeeld, Style beïnvloedt of Shader wordt toegepast op de omtrek of de vulling.
setColor — de belangrijkste methode voor het instellen van de kleur voor alle volgende tekenbewerkingen. De kleur wordt doorgegeven in ARGB-formaat (32-bit geheel getal), waarbij de bovenste 8 bits het alfakanaal zijn en de rest de rode, groene en blauwe kanalen. De waarde 0xFF0000FF stelt een ondoorzichtige blauwe kleur in.
De methode setAlpha maakt het mogelijk om de transparantie onafhankelijk te regelen in het bereik van 0 (volledig transparant) tot 255 (volledig ondoorzichtig). In tegenstelling tot het specificeren van alfa in setColor, beïnvloedt deze methode niet de reeds ingestelde kleurtint — het moduleert alleen de algemene transparantie. Dit is handig voor animaties van het verschijnen en verdwijnen van elementen zonder kleurwijziging.
ColorFilter — een mechanisme voor kleurtransformatie van elke pixel vóór het tekenen. Drie modi worden ondersteund: LightingColorFilter voor vermenigvuldiging en optelling van kanalen, PorterDuffColorFilter voor overvloeiing met mengmodi en ColorMatrixColorFilter voor volledige matrix transformatie. ColorFilter wordt toegepast na Shader, maar vóór uitvoer naar Canvas.
Voor de meeste taken zijn standaard setColor of setAlpha voldoende. ColorFilter wordt voornamelijk gebruikt voor effecten van ontkleuring, sepia of omkering. Het gebruik van ColorFilter verhoogt de GPU-belasting, daarom raadt Google aan het gebruik ervan in cyclische aanroepen van onDraw te minimaliseren.
| Methode | Beschrijving | Prestaties |
|---|---|---|
| setColor | Stelt kleur in ARGB in | O(1) — geen overhead |
| setAlpha | Regelt transparantie (0-255) | O(1) — lichte bewerking |
| setColorFilter | Past kleurcorrectie toe | O(n) — beïnvloedt FPS bij veelvuldig gebruik |
De methode setStyle accepteert een van de drie waarden van Paint.Style: FILL (vulling), STROKE (omtrek) of FILL_AND_STROKE (gelijkzeitig). Afhankelijk van de stijlkeuze wordt de figuur weergegeven als silhouet, als skelet of als omtrek met interne vulling. Standaard wordt Paint gemaakt met de stijl FILL.
setStrokeWidth stelt de lijn dikte in pixels in voor de STROKE-modus. Voor afgeronde vormen en afgeronde hoeken worden setStrokeCap (Cap.ROUND, BUTT, SQUARE) en setStrokeJoin (Join.MITER, ROUND, BEVEL) gebruikt. Deze parameters hebben een kritieke invloed op het uiterlijk van grafieken, paden en randen in aangepaste Views.
Bij een dikte van minder dan 1 pixel wordt de lijn getekend met subpixel-nauwkeurigheid, maar kan er wazig uitzien op schermen met een lage dichtheid. Gebruik voor Android Retina-displays TypedValue.applyDimension voor het omrekenen van dp naar pixels. Een dikte van 2 dp zorgt voor duidelijke zichtbaarheid op de meeste apparaten.
DashPathEffect creëert gestippelde en streepjeslijnen. De constructor accepteert een array van lengtes van afwisselende streepjes en spaties en een beginfaseverschuiving. Bijvoorbeeld, de array [10, 5, 3, 5] creëert een lijn met een lang streepje, korte spatie, kort streepje en spatie. Dit effect wordt actief gebruikt in grafische editors en annotatietools.
Het combineren van stijlen gebeurt via setPathEffect. Door CornerPathEffect, DashPathEffect en DiscretePathEffect te combineren, kunnen complexe visuele lijnen worden gemaakt voor diagrammen, bijschriften en decoratieve elementen. Elk PathEffect wordt op de CPU berekend, dus in animaties met veel lijnen wordt aanbevolen het effect vooraf te rasteren naar 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 — een object dat het lettertype voor alle tekstbewerkingen van Paint bepaalt. Android ondersteunt systeemlettertypen (Roboto, Noto Sans), aangepaste lettertypen uit assets-bronnen en lettertypen die via de Downloadable Fonts API worden geladen. Het instellen van Typeface gebeurt via setTypeface op de Paint-instantie.
De methode setTextSize stelt de lettergrootte in pixels in. Voor correcte weergave op verschillende schermen wordt aanbevolen de grootte in sp op te geven met TypedValue.applyDimension. De regelafstand wordt geregeld via setTextScaleX voor horizontale uitrekking en is opgenomen in de ingebouwde ondersteuning voor MultiLine tekst via Canvas.drawText.
Voor tekstuitlijning wordt setTextAlign gebruikt met de waarden LEFT, CENTER en RIGHT. Bij CENTER wordt de x-coördinaat die aan drawText wordt doorgegeven het centrale punt van de tekst — dit is vooral handig voor bijschriften onder iconen en titels binnen vormen. Voor nauwkeurige positionering worden de methoden measureText en getTextBounds gebruikt, die de breedte en de begrenzingsrechthoek van de tekst retourneren.
setUnderlineText en setStrikeThruText schakelen respectievelijk onderstrepen en doorhalen in. Deze parameters werken op het niveau van het lettertype en worden toegepast op alle tekst die door de betreffende Paint wordt getekend. Voor flexibele opmaak van verschillende delen van dezelfde regel, gebruik je afzonderlijke Paint-objecten met verschillende instellingen of schakel je parameters tussen drawText-aanroepen.
| Methode | Doel | Meeteenheid |
|---|---|---|
| setTextSize | Lettergrootte | px (pixels) |
| setTextAlign | Horizontale uitlijning | LEFT, CENTER, RIGHT |
| setTypeface | Lettertype | Typeface object |
| setUnderlineText | Onderstrepen | Boolean |
Shader — de basisklasse voor het vullen van vormen met verlopen, bitmap texturen en composities. Via de methode setShader kan elk van de subklassen worden toegewezen: LinearGradient, RadialGradient, SweepGradient, BitmapShader of ComposeShader. Shader vervangt de door setColor ingestelde kleur en wordt toegepast op alle getekende elementen.
LinearGradient creëert een vloeiende overgang tussen twee of meer kleuren langs een rechte lijn. De constructor accepteert begin- en eindpunten, een array van kleuren en hun posities (tegelmodus). De tegelmodus bepaalt het gedrag buiten het verloop: CLAMP (herhaling van de laatste kleur), MIRROR (spiegeling) of REPEAT (herhaling). LinearGradient wordt actief gebruikt voor achtergrondvullingen en voortgangsbalken.
RadialGradient creëert een cirkelvormig verloop van het midden naar de randen. Het midden wordt bepaald door coördinaten, de straal definieert het gebied van kleurovergang. Het uiterlijk van radiaal verloop lijkt op verlichting door een puntbron — dit wordt vaak gebruikt voor het simuleren van gloeiende knoppen en verlichting van actieve elementen.
BlurMaskFilter voegt een vervagingseffect toe rond getekende elementen. De constructor accepteert de vervagingsstraal en stijl: NORMAL (vervaging in alle richtingen), INNER (alleen binnen de vorm), OUTER (alleen buiten) en SOLID (vorm + externe vervaging). BlurMaskFilter werkt met alle soorten Paint en wordt vaak gebruikt voor het maken van schaduwen en gloei-effecten.
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))
}
Laten we een compleet voorbeeld bekijken van een aangepaste View die een cirkel tekent met een verloopvulling en een tekstbijschrift. De combinatie van Paint en Canvas maakt het mogelijk om complexe graphics te creëren met minimale code. Alle instellingen zijn voor de prestaties naar de initialisatie verplaatst.
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("Verloop", 200f, 210f, textPaint)
}
}
In de code worden twee afzonderlijke Paint-objecten gebruikt: één voor het vullen van de cirkel met een radiaal verloop, de tweede voor tekst met schaduw via BlurMaskFilter. Een dergelijke scheiding maakt het mogelijk om parameters onafhankelijk te configureren en het resetten van de Paint-status tussen het tekenen van verschillende elementtypen te voorkomen. Voor betere prestaties worden beide Paint-objecten in de constructor gemaakt, niet in onDraw.
Bij het schalen op apparaten met verschillende pixeldichtheid moeten de afmetingen worden herberekend via TypedValue.applyDimension. Zonder dit zullen tekst en verloop er anders uitzien op mdpi- en xxxhdpi-schermen. In het voorbeeld is de tekstgrootte ingesteld in sp, wat zich automatisch aanpast aan de systeeminstellingen voor de lettergrootte van de gebruiker.
Veelgestelde vragen
Canvas voert tekenbewerkingen uit (drawCircle, drawLine), terwijl Paint de stijl bepaalt — kleur, dikte, lettertype. Canvas bevat geen stijlinstellingen, dus zonder Paint heeft geen enkele tekenbewerking een visueel effect.
Ja, één Paint-object kan worden hergebruikt voor meerdere vormen. Het wordt aanbevolen om afzonderlijke Paint-objecten te maken voor verschillende elementtypen (achtergrond, tekst, omtrek), maar niet voor elke vorm — dit vermindert de belasting van de garbage collector.
De methode reset herstelt Paint naar een staat die gelijkwaardig is aan een nieuwe instantie. Als alternatief kan set met een vlag worden gebruikt, maar reset heeft de voorkeur voor leesbaarheid van de code. Na reset krijgen alle stijlparameters de standaardwaarden.
Het maken van Paint binnen onDraw veroorzaakt allocatie in elk frame, wat leidt tot GC-bevriezingen. Alle Paint-objecten moeten worden gemaakt in de constructor van de View. Het wijzigen van parameters in onDraw via setters is veilig en creëert geen nieuwe objecten.
Tekst in Android wordt altijd getekend met een transparante achtergrond. De methode drawText geeft alleen glyphs weer, zonder achtergrondrechthoek. Als er een achtergrond onder de tekst nodig is, teken dan eerst een rechthoek via drawRoundRect met een aparte Paint en dan de tekst.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook