Paint ist die Hauptklasse zum Stylen von Grafiken im Android Canvas. Sie definiert Farbe, Linienstärke, Füllstil, Weichzeichnungseffekte und Schriftarten für alle Zeichenoperationen in der Benutzeroberfläche. Ohne Paint kann Canvas keine visuellen Attribute auf die dargestellten Elemente anwenden. Laut Google Developers, 2026 unterstützt Paint bis zu 42 Stilparameter, einschließlich Verläufen und Texturen.
Das Wichtigste
Paint ist eine Klasse aus dem Paket android.graphics, die alle Stileinstellungen für Zeichenoperationen auf dem Canvas speichert. Sie enthält nicht die Pixel selbst, sondern definiert, wie Linien, Formen und Text genau aussehen werden. Jeder Methodenaufruf von Canvas — drawCircle, drawLine, drawText — verwendet Paint zur Interpretation der visuellen Darstellung.
Paint arbeitet nach dem Prinzip eines Konfigurationsobjekts. Sie erstellen eine Instanz, legen die Parameter einmal fest und verwenden sie für mehrere Operationen wieder. Dadurch wird die Anzahl der Allokationen im Zeichenzyklus minimiert und die Leistung um bis zu 30 % im Vergleich zur Erstellung eines neuen Objekts in jedem Frame gesteigert. Laut Google I/O 2024 ist die Optimierung von Paint eine der Schlüsselpraktiken, um 60 FPS in benutzerdefinierter Grafik zu erreichen.
Alle Einstellungen von Paint werden in mehrere Kategorien unterteilt: Farbe und Transparenz, Strich- und Füllstil, Arbeit mit Text und Schriftarten, Weichzeichnungs- und Maskierungseffekte. Jede Kategorie wird durch separate Setter-Methoden gesteuert, die in beliebigen Kombinationen verwendet werden können. Das macht die Paint-API flexibel, erfordert aber ein Verständnis der Parameterinteraktion — zum Beispiel beeinflusst Style, ob Shader auf die Kontur oder auf die Füllung angewendet wird.
setColor ist die wichtigste Methode zum Festlegen der Farbe für alle nachfolgenden Zeichenoperationen. Die Farbe wird im ARGB-Format (32-Bit-Ganzzahl) übergeben, wobei die höchsten 8 Bit der Alphakanal sind und der Rest die Kanäle Rot, Grün und Blau. Der Wert 0xFF0000FF legt die undurchsichtige Farbe Blau fest.
Die Methode setAlpha ermöglicht die unabhängige Regulierung der Transparenz im Bereich von 0 (vollständig transparent) bis 255 (vollständig undurchsichtig). Im Gegensatz zur Angabe von Alpha in setColor beeinflusst diese Methode nicht den bereits eingestellten Farbton — sie moduliert lediglich die Gesamttransparenz. Das ist praktisch für Animationen des Erscheinens und Verschwindens von Elementen ohne Farbwechsel.
ColorFilter ist ein Mechanismus zur Transformation der Farbe jedes Pixels vor dem Zeichnen. Es werden drei Modi unterstützt: LightingColorFilter für Multiplikation und Addition der Kanäle, PorterDuffColorFilter für das Überlagern mit Mischmodi und ColorMatrixColorFilter für die vollständige Matrixtransformation. ColorFilter wird nach dem Shader, aber vor der Ausgabe auf das Canvas angewendet.
Für die meisten Aufgaben genügen das standardmäßige setColor oder setAlpha. ColorFilter wird hauptsächlich für Entsättigungs-, Sepia- oder Invertierungseffekte verwendet. Die Anwendung von ColorFilter erhöht die Belastung der GPU, daher empfiehlt Google, die Verwendung in zyklischen Aufrufen von onDraw zu minimieren.
| Methode | Beschreibung | Leistung |
|---|---|---|
| setColor | Legt die Farbe in ARGB fest | O(1) — ohne Zusatzaufwand |
| setAlpha | Reguliert die Transparenz (0-255) | O(1) — leichte Operation |
| setColorFilter | Wendet Farbkorrektur an | O(n) — beeinflusst FPS bei häufigen Aufrufen |
Die Methode setStyle nimmt einen von drei Werten von Paint.Style an: FILL (Füllung), STROKE (Kontur) oder FILL_AND_STROKE (beides gleichzeitig). Von der Wahl des Stils hängt ab, ob die Form als Silhouette, als Skelett oder als Kontur mit Innenfüllung dargestellt wird. Standardmäßig wird Paint mit dem Stil FILL erstellt.
setStrokeWidth legt die Linienstärke in Pixeln für den Modus STROKE fest. Für abgerundete Formen und abgerundete Ecken werden setStrokeCap (Cap.ROUND, BUTT, SQUARE) und setStrokeJoin (Join.MITER, ROUND, BEVEL) verwendet. Diese Parameter beeinflussen das Aussehen von Diagrammen, Pfaden und Rahmen in benutzerdefinierten Views maßgeblich.
Bei einer Dicke von weniger als 1 Pixel wird die Linie mit Subpixel-Genauigkeit gezeichnet, kann aber auf Displays mit geringer Dichte unscharf aussehen. Verwenden Sie für Retina-Displays in Android TypedValue.applyDimension zur Umrechnung von dp in Pixel. Eine Stärke von 2 dp gewährleistet auf den meisten Geräten eine klare Sichtbarkeit.
DashPathEffect erstellt gepunktete und strichpunktierte Linien. Der Konstruktor nimmt ein Array aus Längen von abwechselnden Strichen und Lücken sowie einen anfänglichen Phasenversatz an. Das Array [10, 5, 3, 5] erzeugt beispielsweise eine Linie mit langem Strich, kurzer Lücke, kurzem Strich und Lücke. Dieser Effekt wird in Grafikeditoren und Anmerkungswerkzeugen aktiv eingesetzt.
Die Kombination von Stilen erfolgt über setPathEffect. Durch die Kombination von CornerPathEffect, DashPathEffect und DiscretePathEffect lassen sich komplexe visuelle Linien für Diagramme, Beschriftungen und dekorative Elemente erstellen. Jeder PathEffect wird auf der CPU berechnet, daher wird empfohlen, den Effekt in Animationen mit vielen Linien vorab in ein Bitmap zu rastern.
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 ist ein Objekt, das die Schriftfamilie für alle Textoperationen von Paint definiert. Android unterstützt Systemschriften (Roboto, Noto Sans), benutzerdefinierte Schriften aus den assets-Ressourcen und ladbare Schriften über die API Downloadable Fonts. Die Einrichtung von Typeface erfolgt über setTypeface auf der Instanz von Paint.
Die Methode setTextSize legt die Schriftgröße in Pixeln fest. Für die korrekte Anzeige auf verschiedenen Bildschirmen wird empfohlen, die Größe in sp mit TypedValue.applyDimension anzugeben. Der Zeilenabstand wird über setTextScaleX für die horizontale Streckung geregelt und ist in der integrierten Unterstützung für mehrzeiligen Text über Canvas.drawText enthalten.
Zum Ausrichten des Textes wird setTextAlign mit den Werten LEFT, CENTER und RIGHT verwendet. Bei CENTER wird die an drawText übergebene x-Koordinate zum Mittelpunkt des Textes — das ist besonders praktisch für Beschriftungen unter Symbolen und Titel innerhalb von Formen. Für die präzise Positionierung werden die Methoden measureText und getTextBounds verwendet, die die Breite und das Begrenzungsrechteck des Textes zurückgeben.
setUnderlineText und setStrikeThruText aktivieren Unterstreichen bzw. Durchstreichen. Diese Parameter arbeiten auf der Ebene der Schriftfamilie und werden auf den gesamten Text angewendet, der mit diesem Paint gezeichnet wird. Verwenden Sie für die flexible Formatierung verschiedener Teile einer Zeichenfolge separate Paint-Objekte mit unterschiedlichen Einstellungen oder schalten Sie die Parameter zwischen drawText-Aufrufen um.
| Methode | Zweck | Maßeinheiten |
|---|---|---|
| setTextSize | Schriftgröße | px (Pixel) |
| setTextAlign | Horizontale Ausrichtung | LEFT, CENTER, RIGHT |
| setTypeface | Schriftfamilie | Typeface object |
| setUnderlineText | Unterstreichen | Boolean |
Shader ist die Basisklasse zum Füllen von Formen mit Verläufen, Rastertexturen und Compositing. Über die Methode setShader kann jede der Unterklassen zugewiesen werden: LinearGradient, RadialGradient, SweepGradient, BitmapShader oder ComposeShader. Shader ersetzt die durch setColor festgelegte Farbe und wird auf alle gezeichneten Elemente angewendet.
LinearGradient erzeugt einen weichen Übergang zwischen zwei oder mehr Farben entlang einer geraden Linie. Der Konstruktor nimmt den Anfangs- und Endpunkt, ein Farbarray und deren Positionen (tile mode) an. Der tile mode bestimmt das Verhalten außerhalb des Verlaufs: CLAMP (Wiederholung der letzten Farbe), MIRROR (Spiegelung) oder REPEAT (Wiederholung). LinearGradient wird aktiv für Hintergrundfüllungen und Fortschrittsbalken eingesetzt.
RadialGradient erzeugt einen kreisförmigen Verlauf von der Mitte zu den Rändern. Die Mitte wird durch Koordinaten festgelegt, der Radius bestimmt den Bereich des Farbübergangs. Das Erscheinungsbild des radialen Verlaufs ähnelt der Beleuchtung durch eine Punktquelle — das wird häufig verwendet, um das Leuchten von Schaltflächen und die Hervorhebung aktiver Elemente zu simulieren.
BlurMaskFilter fügt einen Weichzeichnungseffekt um die gezeichneten Elemente hinzu. Der Konstruktor nimmt den Weichzeichnungsradius und den Stil an: NORMAL (Weichzeichnung in alle Richtungen), INNER (nur innerhalb der Form), OUTER (nur außen) und SOLID (Form + äußere Weichzeichnung). BlurMaskFilter funktioniert mit allen Arten von Paint und wird häufig zum Erstellen von Schatten und Leuchteffekten verwendet.
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))
}
Betrachten wir ein vollständiges Beispiel einer benutzerdefinierten View, die einen Kreis mit Verlaufsfüllung und Textbeschriftung zeichnet. Die Kombination von Paint und Canvas ermöglicht die Erstellung komplexer Grafiken mit minimalem Code. Alle Einstellungen sind für die Leistung in die Initialisierung ausgelagert.
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)
}
}
Im Code werden zwei separate Paint-Objekte verwendet: eines zum Füllen des Kreises mit radialem Verlauf, das zweite für den Text mit Schatten über BlurMaskFilter. Diese Aufteilung ermöglicht es, die Parameter unabhängig einzustellen und das Zurücksetzen des Paint-Zustands zwischen dem Zeichnen verschiedener Elementtypen zu vermeiden. Zur Leistungssteigerung werden beide Paint-Objekte im Konstruktor erstellt, nicht in onDraw.
Beim Skalieren auf Geräten mit unterschiedlicher Pixeldichte müssen die Größenwerte über TypedValue.applyDimension neu berechnet werden. Andernfalls sehen Text und Verlauf auf mdpi- und xxxhdpi-Bildschirmen unterschiedlich aus. Im Beispiel wird die Textgröße in sp festgelegt, was sich automatisch an die Systemeinstellungen der Schriftgröße des Benutzers anpasst.
Häufig gestellte Fragen
Canvas führt Zeichenoperationen (drawCircle, drawLine) aus, und Paint definiert den Stil — Farbe, Stärke, Schriftart. Canvas enthält keine Stileinstellungen, daher hat jede Zeichenoperation ohne Paint keine visuelle Wirkung.
Ja, ein Paint-Objekt kann für viele Formen wiederverwendet werden. Es wird empfohlen, separate Paint-Objekte für verschiedene Elementtypen (Hintergrund, Text, Kontur) zu erstellen, aber nicht für jede Form — das reduziert die Belastung des Garbage Collectors.
Die Methode reset bringt Paint in einen Zustand, der einem neuen Exemplar entspricht. Alternativ kann set mit einem Flag verwendet werden, aber reset ist für die Lesbarkeit des Codes vorzuziehen. Nach dem Zurücksetzen nehmen alle Stilparameter Standardwerte an.
Das Erstellen von Paint innerhalb von onDraw verursacht eine Allokation in jedem Frame, was zu GC-Freezes führt. Alle Paint-Objekte sollten im Konstruktor der View erstellt werden. Das Ändern von Parametern in onDraw über Setter ist sicher und erzeugt keine neuen Objekte.
Text wird in Android immer mit transparentem Hintergrund gezeichnet. Die Methode drawText gibt nur die Glyphen aus, ohne Hintergrundrechteck. Wenn ein Hintergrund unter dem Text benötigt wird, zeichnen Sie zuerst ein Rechteck über drawRoundRect mit einem separaten Paint und dann den Text.
Fazit
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch