Canvas i Android: vad är det, Canvas-klass och draw-metoder

Författare: IT Sectr Publicerad: 2026-07-21 Lästid: 7 min

Canvas i Android — är en klass från paketet android.graphics som tillhandahåller API för 2D-ritning på View. Canvas fungerar som en duk på vilken utvecklaren ritar geometriska figurer, text, bilder och sökvägar med hjälp av olika draw*-metoder. Enligt Android Developers Documentation (2025) är Canvas det främsta verktyget för anpassad ritning i Android och används tillsammans med Paint-klassen för att ställa in stilar och färger. Varje anrop till onDraw() får en färdig Canvas-instans kopplad till vyens bitmap-buffert.

Huvudpunkter

  • Canvas — klass för 2D-ritning i Android, tillhandahåller metoder drawRect, drawCircle, drawText, drawBitmap och andra
  • Paint — klass som bestämmer ritsstil: färg, tjocklek, fyllning, effekter (skugga, gradient)
  • onDraw(Canvas) — View-metod där all ritning via den mottagna Canvas sker
  • Canvas.save() och restore() — hantering av transformationsstack för nästlade koordinatsystemomvandlingar
  • Path — klass för att bygga godtyckliga konturer och kurvor, skickas till drawPath(Path, Paint)

Vad är Canvas i Android

Canvas — är den centrala 2D-grafikklassen i Android som tillhandahåller metoder för ritning på en yta. Varje Canvas är kopplad till en Bitmap — ett minnesområde där resultaten av ritoperationer skrivs. När en View ritas om skickar systemet till onDraw() en Canvas som redan är kopplad till denna vy's buffert.

Canvas arbetar i ett koordinatsystem där (0,0) är det övre vänstra hörnet, X-axeln går åt höger och Y-axeln nedåt. Alla ritoperationer använder Canvas aktuella tillstånd, inklusive transformationsmatris, klippområde (clip) och Paint-stil. Enligt Android Documentation (2025) innehåller Canvas API över 30 draw*-metoder för olika typer av grafiska primitiver.

Canvas och hårdvaruacceleration

Från och med Android 3.0 (API 11) stöder Canvas hårdvaruacceleration via DisplayList. I accelererat läge skrivs Canvas-operationer till DisplayList och exekveras sedan på GPU:n. Detta ger en betydande prestandaökning men inför begränsningar: vissa Canvas-operationer (clipPath med icke-Path-klipp) stöds inte i accelererat läge.

Huvudsakliga Canvas-metoder för ritning

Canvas tillhandahåller en uppsättning metoder för att rita grundläggande primitiver. Varje metod tar emot geometriska parametrar och ett Paint-objekt som bestämmer den visuella stilen.

MetodSyfteExempel
drawRect()Rita rektangelcanvas.drawRect(10f, 10f, 100f, 100f, paint)
drawCircle()Rita cirkelcanvas.drawCircle(50f, 50f, 30f, paint)
drawLine()Rita linjecanvas.drawLine(0f, 0f, 100f, 100f, paint)
drawText()Rita textcanvas.drawText("Hello", 10f, 20f, paint)
drawBitmap()Rita bildcanvas.drawBitmap(bitmap, 0f, 0f, paint)
drawPath()Rita godtycklig sökvägcanvas.drawPath(path, paint)
drawOval()Rita ovalcanvas.drawOval(rectF, paint)
drawArc()Rita båge eller sektorcanvas.drawArc(rectF, 0f, 90f, true, paint)

Varje metod kan anropas i valfri ordning — Canvas ritar i anropsordningen och lägger nya element ovanpå tidigare. För komplexa kompositioner används tekniken med flerskiktsritning med sparning och återställning av Canvas tillstånd.

Paint-klass: konfiguration av stilar och effekter

Paint — är klassen som bestämmer hur Canvas ska rita. Utan Paint är Canvas-metoderna värdelösa — den ställer in färg, linjetjocklek, fyllningsstil, textstorlek, effekter (skugga, gradient, oskärpa) och blandningsläge.

Paint har viktiga egenskaper: color (färg), style (FILL, STROKE eller FILL_AND_STROKE), strokeWidth (linjetjocklek), textSize (textstorlek), isAntiAlias (kantutjämning), shader (gradient eller bild). Att skapa ett Paint-objekt är en dyr operation, därför bör det skapas en gång och återanvändas.

kotlin
private val fillPaint = Paint().apply {
    color = Color.parseColor("#FF6200EE")
    style = Paint.Style.FILL
    isAntiAlias = true
}

private val strokePaint = Paint().apply {
    color = Color.WHITE
    style = Paint.Style.STROKE
    strokeWidth = 4f
    isAntiAlias = true
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    canvas.drawCircle(100f, 100f, 80f, fillPaint)
    canvas.drawCircle(100f, 100f, 80f, strokePaint)
}

I detta exempel används två Paint: en för att fylla cirkeln med lila, den andra för vit kontur. Uppdelningen i fill och stroke är en standardpraxis som möjliggör flexibel hantering av utseendet utan att återskapa objekt.

Shader och gradienter

För gradientfyllningar accepterar Paint en Shader — underklasser LinearGradient, RadialGradient, SweepGradient. Shader kopplas till Paint via metoden setShader() och bestämmer hur färgen förändras över ritområdet.

Canvas-transformeringar: translate, rotate, scale

Canvas stöder matristransformeringar av koordinatsystemet: translate() (förskjutning), rotate() (rotation), scale() (skalning) och skew() (snedställning). Transformeringar ackumuleras: varje efterföljande anrop appliceras ovanpå tidigare.

Hantering av transformationsstacken sker via save() och restore(). save() sparar Canvas aktuella tillstånd (matris, clip) i stacken, restore() återställer det senast sparade tillståndet. Mellan save() och restore() kan det finnas nästlade transformeringar.

kotlin
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    canvas.save() // Spara initialt tillstånd
    canvas.translate(100f, 100f) // Flytta origo

    // Första kvadraten
    canvas.drawRect(0f, 0f, 50f, 50f, fillPaint)

    canvas.save() // Spara efter flytt
    canvas.rotate(45f, 25f, 25f) // Rotera runt kvadratens centrum

    // Roterad kvadrat
    canvas.drawRect(0f, 0f, 50f, 50f, strokePaint)
    canvas.restore() // Återställ efter rotation

    canvas.restore() // Återställ initialt tillstånd
}

Använd alltid save() före transformeringar och restore() efter deras slutförande. Obalanserade save/restore leder till ackumulering av matrisen och felaktig ritning av efterföljande element.

Canvas med Bitmap och Path för komplex grafik

För komplex grafik kombineras Canvas med Bitmap och Path. Bitmap används för att ladda bilder och cachelagra renderade ramar. Path — för att bygga godtyckliga Bezier-kurvor, polygoner och komplexa konturer.

Offscreen Bitmap-buffert

Teknik för offscreen-rendering: en Bitmap skapas, en komplex scen ritas på den via en separat Canvas, och sedan visas den färdiga Bitmap i onDraw() via drawBitmap(). Detta gör det möjligt att uppdatera komplex grafik utan att helt rita om varje ram.

kotlin
private var offscreenBitmap: Bitmap? = null
private var offscreenCanvas: Canvas? = null

fun buildOffscreenScene(width: Int, height: Int) {
    offscreenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    offscreenCanvas = Canvas(offscreenBitmap)

    // Rendera scen en gång
    offscreenCanvas!!.drawColor(Color.WHITE)
    drawGrid(offscreenCanvas!!)
    drawComplexShape(offscreenCanvas!!)
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    offscreenBitmap?.let { canvas.drawBitmap(it, 0f, 0f, null) }
}

Path används för att bygga komplexa konturer: Bezier-kurvor (quadTo, cubicTo), bågar (arcTo), linjer (lineTo). Path kan vara sluten (close()) för fyllda former eller öppen för linjer. Huvudmetoderna drawPath() kombinerar Path och Paint för slutlig ritning.

Optimering av Canvas-ritning

Prestandan för Canvas-ritning påverkar direkt applikationens FPS. Huvudproblem: överdrivna allokeringar i onDraw(), frekventa invalidate() och suboptimal användning av hårdvaruacceleration.

Skapa objekt utanför onDraw()

Paint, Path, Rect, RectF och andra objekt bör skapas en gång i initieraren eller setup()-metoden. Varje allokering i onDraw() belastar garbage collection, vilket leder till mikro-hackningar. Undantag — static eller companion object för oföränderliga objekt.

Använd clipRect() för att begränsa område

Om en stor del av View är dold utanför det synliga området (t.ex. i ScrollView), använd canvas.clipRect() för att begränsa ritningen. Hårdvaruacceleration optimerar i detta fall ytterligare beskärning av osynliga pixlar.

kotlin
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    // Begränsa till synligt område
    canvas.save()
    canvas.clipRect(scrollX, scrollY, scrollX + width, scrollY + height)

    // Rendera stor scen
    renderScene(canvas)
    canvas.restore()
}

Använd View.setLayerType() med LAYER_TYPE_HARDWARE för View med komplex Canvas-grafik som sällan uppdateras. För ofta uppdaterade animationer använder du LAYER_TYPE_NONE för att undvika dyr uppdatering av hårdvarulagret. Profilera genom GPU Profile Rendering och Android Studio Profiler.

Vanliga frågor

Kan Canvas skapas utan View?

Ja, du kan skapa Canvas(Bitmap) — en konstruktor som tar emot Bitmap. Detta används för offscreen-rendering: du ritar på Bitmap och visar den sedan via drawBitmap(). Canvas kan också skapas från Surface (för SurfaceView) eller via Picture.

Vad är skillnaden mellan Canvas och SurfaceView?

Canvas — är API för ritning på View i UI-tråden. SurfaceView — är en separat Surface som kan uppdateras från bakgrundstråden via sin egen Canvas (lockCanvas() / unlockCanvasAndPost()). SurfaceView är att föredra för spel och video.

Varför ritar inte Canvas efter transformering?

Den vanligaste orsaken är obalanserade save() och restore(). Om restore() inte anropas efter transformering (translate, rotate) förblir Canvas i det ändrade koordinatsystemet och efterföljande element ritas med förskjutning. Kontrollera save()/restore()-paren.

Hur ritar jag text i mitten av Canvas?

Använd Paint.setTextAlign(Paint.Align.CENTER) för horisontell justering och Paint.getTextBounds() eller Paint.descent() / ascent() för vertikal. Centrering: canvas.drawText(text, centerX, centerY - (ascent + descent) / 2, paint).

Stöder Canvas animation?

Canvas i sig självt animerar inte — det ritar bara det aktuella tillståndet. Animation uppnås genom sekventiella anrop till invalidate() (eller postInvalidateOnAnimation()), varje gång ritas en ny bildruta i onDraw(). För jämna animationer använder du ValueAnimator eller Choreographer för synkronisering med Vsync.

Sammanfattning

  • Canvas — central 2D-ritningsklass i Android, tillhandahåller draw*-metoder för ritning av primitiver, text och bilder
  • Paint — bestämmer visuell stil (färg, tjocklek, fyllning, shaders); skapas en gång och återanvänds
  • save() / restore() — hantering av transformationsstacken; varje transformering måste vara i ett save/restore-par
  • Path — byggande av godtyckliga konturer och Bezier-kurvor för komplex vektorgrafik
  • Offscreen Bitmap — teknik för cachelagring av komplexa scener via Canvas(Bitmap) för att minska belastningen på onDraw()
  • Hårdvaruacceleration — GPU-acceleration för Canvas sedan Android 3.0, inför begränsningar för vissa operationer (clipPath)
  • Profilering — GPU Profile Rendering och Android Studio Profiler är obligatoriska för att hitta flaskhalsar i onDraw()

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också