Canvas Androidban: mi ez, Canvas osztály és draw metódusok

Szerző: IT Sectr Megjelenés: 2026-07-21 Olvasási idő: 7 perc

Canvas Androidban — egy osztály az android.graphics csomagból, amely API-t biztosít a 2D rajzoláshoz View-n. A Canvas úgy működik, mint egy vászon, amelyre a fejlesztő geometriai alakzatokat, szöveget, képeket és útvonalakat rajzol különböző draw* metódusok segítségével. Az Android Developers Documentation (2025) szerint a Canvas a fő eszköz az egyedi rajzoláshoz Androidban, és a Paint osztállyal együtt használatos a stílusok és színek beállításához. Minden onDraw() hívás egy kész Canvas példányt kap, amely a nézet bitmap pufferéhez van kapcsolva.

Főbb pontok

  • Canvas — osztály a 2D rajzoláshoz Androidban, drawRect, drawCircle, drawText, drawBitmap és egyéb metódusokat biztosít
  • Paint — osztály, amely meghatározza a rajzolási stílust: szín, vastagság, kitöltés, effektek (árnyék, átmenet)
  • onDraw(Canvas) — a View metódusa, amelyben a teljes rajzolás a kapott Canvas segítségével történik
  • Canvas.save() és restore() — a transzformációs verem kezelése beágyazott koordinátarendszer-transzformációkhoz
  • Path — osztály tetszőleges kontúrok és görbék építéséhez, átadva a drawPath(Path, Paint) metódusnak

Mi az a Canvas Androidban

Canvas — a központi 2D grafikai osztály Androidban, amely metódusokat biztosít a síkra rajzoláshoz. Minden Canvas egy Bitmap-hez van kapcsolva — egy memóriaterülethez, amelybe a rajzolási műveletek eredményei kerülnek. Amikor a View újrarajzolódik, a rendszer az onDraw()-nak egy Canvas-t ad át, amely már ehhez a View-hoz van kapcsolva.

A Canvas egy koordinátarendszerben működik, ahol (0,0) a bal felső sarok, az X tengely jobbra, az Y tengely lefelé mutat. Minden rajzolási művelet a Canvas aktuális állapotát használja, beleértve a transzformációs mátrixot, a vágási területet (clip) és a Paint stílust. Az Android Documentation (2025) szerint a Canvas API több mint 30 draw* metódust tartalmaz különböző típusú grafikai primitívekhez.

Canvas és hardvergyorsítás

Android 3.0 (API 11) óta a Canvas támogatja a hardvergyorsítást a DisplayList segítségével. Gyorsított módban a Canvas műveletek a DisplayList-be íródnak, majd a GPU-n hajtódnak végre. Ez jelentős teljesítménynövekedést biztosít, de korlátozásokat vezet be: egyes Canvas műveletek (clipPath nem Path vágással) nem támogatottak gyorsított módban.

A Canvas fő rajzolási metódusai

A Canvas metóduskészletet biztosít az alapvető primitívek rajzolásához. Minden metódus geometriai paramétereket és egy Paint objektumot fogad, amely meghatározza a vizuális stílust.

MetódusCélPélda
drawRect()Téglalap rajzolásacanvas.drawRect(10f, 10f, 100f, 100f, paint)
drawCircle()Kör rajzolásacanvas.drawCircle(50f, 50f, 30f, paint)
drawLine()Vonal rajzolásacanvas.drawLine(0f, 0f, 100f, 100f, paint)
drawText()Szöveg rajzolásacanvas.drawText("Hello", 10f, 20f, paint)
drawBitmap()Kép rajzolásacanvas.drawBitmap(bitmap, 0f, 0f, paint)
drawPath()Tetszőleges útvonal rajzolásacanvas.drawPath(path, paint)
drawOval()Ovális rajzolásacanvas.drawOval(rectF, paint)
drawArc()Ív vagy szektor rajzolásacanvas.drawArc(rectF, 0f, 90f, true, paint)

Minden metódus tetszőleges sorrendben hívható — a Canvas a hívások sorrendjében rajzol, az új elemeket a korábbiak fölé helyezve. Összetett kompozíciókhoz a többrétegű rajzolás technikáját használják a Canvas állapotának mentésével és visszaállításával.

Paint osztály: stílusok és effektek beállítása

Paint — az az osztály, amely meghatározza, hogy a Canvas hogyan fog rajzolni. Paint nélkül a Canvas metódusai haszontalanok — beállítja a színt, vonalvastagságot, kitöltési stílust, szövegméretet, effekteket (árnyék, átmenet, elmosás) és keverési módot.

A Paint kulcsfontosságú tulajdonságai: color (szín), style (FILL, STROKE vagy FILL_AND_STROKE), strokeWidth (vonalvastagság), textSize (szövegméret), isAntiAlias (élsimítás), shader (átmenet vagy kép). A Paint objektum létrehozása költséges művelet, ezért egyszer kell létrehozni és újrahasználni.

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)
}

Ebben a példában két Paint van használatban: az egyik a kör lila színnel való kitöltéséhez, a másik a fehér körvonalhoz. A fill és stroke szétválasztása szokásos gyakorlat, amely lehetővé teszi a megjelenés rugalmas kezelését az objektumok újraalkotása nélkül.

Shader és átmenetek

Az átmenetes kitöltésekhez a Paint egy Shader-t fogad — a LinearGradient, RadialGradient, SweepGradient alosztályokat. A Shader a setShader() metódussal csatlakozik a Paint-hez, és meghatározza, hogy a szín hogyan változik a rajzolási területen.

Canvas transzformációk: translate, rotate, scale

A Canvas támogatja a koordinátarendszer mátrix transzformációit: translate() (eltolás), rotate() (forgatás), scale() (skálázás) és skew() (ferdítés). A transzformációk halmozódnak: minden következő hívás az előzőekre épül.

A transzformációs verem kezelése a save() és restore() segítségével történik. A save() elmenti a Canvas aktuális állapotát (mátrix, clip) a verembe, a restore() visszaállítja az utoljára mentett állapotot. A save() és restore() között beágyazott transzformációk lehetnek.

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

    canvas.save() // Kezdeti állapot mentése
    canvas.translate(100f, 100f) // Origó eltolása

    // Első négyzet
    canvas.drawRect(0f, 0f, 50f, 50f, fillPaint)

    canvas.save() // Mentés eltolás után
    canvas.rotate(45f, 25f, 25f) // Forgatás a négyzet középpontja körül

    // Elforgatott négyzet
    canvas.drawRect(0f, 0f, 50f, 50f, strokePaint)
    canvas.restore() // Visszaállítás forgatás után

    canvas.restore() // Kezdeti állapot visszaállítása
}

Mindig használjon save()-t a transzformációk megkezdése előtt és restore()-t a befejezésük után. A kiegyensúlyozatlan save/restore a mátrix felhalmozódásához és a későbbi elemek helytelen rajzolásához vezet.

Canvas Bitmap és Path segítségével összetett grafikához

Összetett grafikához a Canvas-t Bitmap-pel és Path-sal kombinálják. A Bitmap képek betöltésére és renderelt képkockák gyorsítótárazására szolgál. A Path — tetszőleges Bezier-görbék, sokszögek és összetett kontúrok építésére.

Offscreen Bitmap puffer

Offscreen-renderelés technikája: létrehoznak egy Bitmap-et, amelyre egy külön Canvas segítségével egy összetett jelenetet rajzolnak, majd a kész Bitmap-et az onDraw()-ban a drawBitmap()-en keresztül jelenítik meg. Ez lehetővé teszi az összetett grafika frissítését anélkül, hogy minden képkockát teljesen újrarajzolnának.

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)

    // Jelenet renderelése egyszer
    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 összetett kontúrok építésére szolgál: Bezier-görbék (quadTo, cubicTo), ívek (arcTo), vonalak (lineTo). A Path lehet zárt (close()) kitöltött alakzatokhoz vagy nyitott vonalakhoz. A drawPath() fő metódusok a Path-et és a Paint-et kombinálják a végső rajzoláshoz.

A Canvas rajzolás optimalizálása

A Canvas rajzolás teljesítménye közvetlenül befolyásolja az alkalmazás FPS-ét. Fő problémák: túlzott foglalások az onDraw()-ban, gyakori invalidate() és a hardvergyorsítás nem optimális használata.

Hozzon létre objektumokat az onDraw()-on kívül

A Paint, Path, Rect, RectF és más objektumokat egyszer kell létrehozni az inicializátorban vagy a setup() metódusban. Minden foglalás az onDraw()-ban terheli a garbage collectort, ami mikro-akadásokhoz vezet. Kivétel — static vagy companion object immutable objektumokhoz.

Használja a clipRect()-et a terület korlátozásához

Ha a View nagy része a látható területen kívül rejtőzik (pl. ScrollView-ben), használja a canvas.clipRect()-et a rajzolás korlátozásához. A hardvergyorsítás ebben az esetben tovább optimalizálja a láthatatlan pixelek levágását.

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

    // Vágás a látható területre
    canvas.save()
    canvas.clipRect(scrollX, scrollY, scrollX + width, scrollY + height)

    // Nagy jelenet renderelése
    renderScene(canvas)
    canvas.restore()
}

Használja a View.setLayerType()-ot LAYER_TYPE_HARDWARE-val azon View-hoz, amely ritkán frissülő összetett Canvas grafikával rendelkezik. Gyakran frissülő animációkhoz használja a LAYER_TYPE_NONE-t, hogy elkerülje a hardverréteg költséges frissítését. Profilozzon a GPU Profile Rendering és Android Studio Profiler segítségével.

Gyakran Ismételt Kérdések

Létrehozható Canvas View nélkül?

Igen, létrehozható Canvas(Bitmap) — egy konstruktor, amely Bitmap-et fogad. Ezt offscreen-rendereléshez használják: a Bitmap-re rajzolnak, majd a drawBitmap()-en keresztül jelenítik meg. A Canvas létrehozható Surface-ből (SurfaceView-hoz) vagy Picture-n keresztül is.

Miben különbözik a Canvas a SurfaceView-től?

Canvas — API a View-ra rajzoláshoz az UI szálban. SurfaceView — egy külön Surface, amely a háttérszálból frissíthető saját Canvas segítségével (lockCanvas() / unlockCanvasAndPost()). A SurfaceView előnyösebb játékokhoz és videókhoz.

Miért nem rajzol a Canvas transzformáció után?

A leggyakoribb ok a kiegyensúlyozatlan save() és restore(). Ha a transzformáció (translate, rotate) után nem hívják meg a restore()-t, a Canvas a megváltozott koordinátarendszerben marad, és a későbbi elemek eltolással rajzolódnak. Ellenőrizze a save()/restore() párokat.

Hogyan rajzoljak szöveget a Canvas közepére?

Használja a Paint.setTextAlign(Paint.Align.CENTER)-t vízszintes igazításhoz és a Paint.getTextBounds()-t vagy a Paint.descent() / ascent()-et függőleges igazításhoz. Középre igazítás: canvas.drawText(text, centerX, centerY - (ascent + descent) / 2, paint).

Támogatja a Canvas az animációt?

A Canvas önmagában nem animál — csak az aktuális állapotot rajzolja ki. Az animáció egymást követő invalidate() (vagy postInvalidateOnAnimation()) hívásokkal érhető el, minden alkalommal új képkockát rajzolva az onDraw()-ban. Sima animációkhoz használja a ValueAnimator-t vagy a Choreographer-t a Vsync-hez való szinkronizáláshoz.

Összefoglalás

  • Canvas — központi 2D rajzolási osztály Androidban, draw* metódusokat biztosít primitívek, szöveg és képek rajzolásához
  • Paint — meghatározza a vizuális stílust (szín, vastagság, kitöltés, shaderek); egyszer létrehozva, újrahasználva
  • save() / restore() — a transzformációs verem kezelése; minden transzformációnak save/restore párban kell lennie
  • Path — tetszőleges kontúrok és Bezier-görbék építése összetett vektorgrafikához
  • Offscreen Bitmap — összetett jelenetek gyorsítótárazásának technikája Canvas(Bitmap) segítségével az onDraw() terhelésének csökkentésére
  • Hardvergyorsítás — GPU gyorsítás a Canvas számára Android 3.0 óta, korlátozásokat vezet be egyes műveletekre (clipPath)
  • Profilozás — GPU Profile Rendering és Android Studio Profiler kötelező a szűk keresztmetszetek megtalálásához az onDraw()-ban

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is