Canvas sa Android: ano ito, klase ng Canvas at mga draw method

May-akda: IT Sectr Nai-publish: 2026-07-21 Oras ng pagbabasa: 7 min

Canvas sa Android — ay isang klase mula sa android.graphics package na nagbibigay ng API para sa 2D na pagguhit sa View. Ang Canvas ay gumagana tulad ng isang canvass kung saan ang developer ay gumuhit ng mga geometric na hugis, teksto, larawan at mga landas gamit ang iba't ibang draw* method. Ayon sa Android Developers Documentation (2025), ang Canvas ay ang pangunahing kasangkapan para sa custom na pagguhit sa Android at ginagamit kasama ng Paint class para sa pagtatakda ng mga estilo at kulay. Bawat tawag sa onDraw() ay tumatanggap ng handa nang instance ng Canvas na naka-ugnay sa bitmap buffer ng view.

Mga Pangunahing Punto

  • Canvas — klase para sa 2D na pagguhit sa Android, nagbibigay ng mga method na drawRect, drawCircle, drawText, drawBitmap at iba pa
  • Paint — klase na tumutukoy sa estilo ng pagguhit: kulay, kapal, fill, mga epekto (anino, gradient)
  • onDraw(Canvas) — method ng View kung saan nagaganap ang lahat ng pagguhit sa pamamagitan ng natanggap na Canvas
  • Canvas.save() at restore() — pamamahala ng stack ng mga transformasyon para sa nested na pagbabago ng coordinate system
  • Path — klase para sa pagbuo ng arbitraryong mga contour at kurba, ipinapasa sa drawPath(Path, Paint)

Ano ang Canvas sa Android

Canvas — ay ang sentral na 2D graphics class sa Android na nagbibigay ng mga method para sa pagguhit sa isang surface. Bawat Canvas ay naka-ugnay sa isang Bitmap — isang lugar ng memorya kung saan isinusulat ang mga resulta ng mga operasyon sa pagguhit. Kapag ang View ay na-redraw, ang system ay nagpapasa sa onDraw() ng Canvas na naka-ugnay na sa buffer ng View na ito.

Ang Canvas ay gumagana sa isang coordinate system kung saan ang (0,0) ay ang kaliwang sulok sa itaas, ang X axis ay pakanan, ang Y axis ay pababa. Lahat ng operasyon sa pagguhit ay gumagamit ng kasalukuyang estado ng Canvas, kasama ang transformation matrix, clip area at Paint style. Ayon sa Android Documentation (2025), ang Canvas API ay may kasamang higit sa 30 draw* method para sa iba't ibang uri ng graphics primitives.

Canvas at Hardware Acceleration

Mula noong Android 3.0 (API 11) sinusuportahan ng Canvas ang hardware acceleration sa pamamagitan ng DisplayList. Sa accelerated mode, ang mga operasyon ng Canvas ay isinusulat sa DisplayList at pagkatapos ay isinasagawa sa GPU. Ito ay nagbibigay ng makabuluhang pagtaas sa performance, ngunit nagpapataw ng mga limitasyon: ang ilang operasyon ng Canvas (clipPath na may non-Path clip) ay hindi suportado sa accelerated mode.

Mga pangunahing method ng Canvas para sa pagguhit

Ang Canvas ay nagbibigay ng isang set ng mga method para sa pagguhit ng mga basic primitives. Bawat method ay tumatanggap ng geometric parameters at isang Paint object na tumutukoy sa visual style.

MethodLayuninHalimbawa
drawRect()Pagguhit ng parihabacanvas.drawRect(10f, 10f, 100f, 100f, paint)
drawCircle()Pagguhit ng bilogcanvas.drawCircle(50f, 50f, 30f, paint)
drawLine()Pagguhit ng linyacanvas.drawLine(0f, 0f, 100f, 100f, paint)
drawText()Pagguhit ng tekstocanvas.drawText("Hello", 10f, 20f, paint)
drawBitmap()Pagguhit ng larawancanvas.drawBitmap(bitmap, 0f, 0f, paint)
drawPath()Pagguhit ng arbitraryong landascanvas.drawPath(path, paint)
drawOval()Pagguhit ng obalocanvas.drawOval(rectF, paint)
drawArc()Pagguhit ng arko o sektorcanvas.drawArc(rectF, 0f, 90f, true, paint)

Bawat method ay maaaring tawagin sa kahit anong pagkakasunod-sunod — ang Canvas ay gumuhit ayon sa pagkakasunod-sunod ng mga tawag, inilalagay ang mga bagong elemento sa ibabaw ng mga nauna. Para sa mga komplikadong komposisyon, ginagamit ang technique ng multi-layer na pagguhit na may pag-save at pag-restore ng estado ng Canvas.

Paint class: pag-configure ng mga estilo at epekto

Paint — ay ang klase na tumutukoy kung paano gumuhit ang Canvas. Kung wala ang Paint, ang mga method ng Canvas ay walang silbi — ito ay nagtatakda ng kulay, kapal ng linya, estilo ng fill, laki ng teksto, mga epekto (anino, gradient, blur) at blending mode.

Ang Paint ay may mga pangunahing katangian: color (kulay), style (FILL, STROKE o FILL_AND_STROKE), strokeWidth (kapal ng linya), textSize (laki ng teksto), isAntiAlias (anti-aliasing), shader (gradient o larawan). Ang paggawa ng Paint object ay isang mahal na operasyon, kaya dapat itong gawin nang isang beses at gamitin muli.

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

Sa halimbawang ito, dalawang Paint ang ginagamit: isa para sa pagpuno ng bilog ng kulay lila, ang pangalawa para sa puting outline. Ang paghihiwalay sa fill at stroke ay isang standard na kasanayan na nagpapahintulot ng flexible na pamamahala ng hitsura nang hindi muling ginagawa ang mga object.

Shader at mga Gradient

Para sa gradient fills, ang Paint ay tumatanggap ng Shader — mga subclass na LinearGradient, RadialGradient, SweepGradient. Ang Shader ay ikinakabit sa Paint sa pamamagitan ng method na setShader() at tinutukoy kung paano nagbabago ang kulay sa lugar ng pagguhit.

Mga transformasyon ng Canvas: translate, rotate, scale

Ang Canvas ay sumusuporta sa matrix transformations ng coordinate system: translate() (paglipat), rotate() (pag-ikot), scale() (pag-scale) at skew() (pag-pahilig). Ang mga transformasyon ay nag-iipon: bawat susunod na tawag ay inilalapat sa ibabaw ng mga nauna.

Ang pamamahala ng stack ng mga transformasyon ay ginagawa sa pamamagitan ng save() at restore(). Ang save() ay nagse-save ng kasalukuyang estado ng Canvas (matrix, clip) sa stack, ang restore() ay nagre-restore ng huling na-save na estado. Sa pagitan ng save() at restore() ay maaaring magkaroon ng nested na mga transformasyon.

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

    canvas.save() // I-save ang paunang estado
    canvas.translate(100f, 100f) // Ilipat ang pinagmulan

    // Unang parisukat
    canvas.drawRect(0f, 0f, 50f, 50f, fillPaint)

    canvas.save() // I-save pagkatapos ng paglipat
    canvas.rotate(45f, 25f, 25f) // Ikot sa paligid ng gitna ng parisukat

    // Pinaikot na parisukat
    canvas.drawRect(0f, 0f, 50f, 50f, strokePaint)
    canvas.restore() // I-restore pagkatapos ng pag-ikot

    canvas.restore() // I-restore ang paunang estado
}

Palaging gamitin ang save() bago simulan ang mga transformasyon at restore() pagkatapos ng mga ito. Ang hindi balanseng save/restore ay humahantong sa pag-ipon ng matrix at hindi tamang pagguhit ng mga susunod na elemento.

Canvas na may Bitmap at Path para sa komplikadong graphics

Para sa komplikadong graphics, ang Canvas ay pinagsama sa Bitmap at Path. Ang Bitmap ay ginagamit para sa pag-load ng mga larawan at pag-cache ng mga na-render na frame. Ang Path — para sa pagbuo ng arbitraryong Bezier curves, polygons at komplikadong contours.

Offscreen Bitmap Buffer

Technique ng offscreen-rendering: gumawa ng Bitmap, iguhit ang komplikadong eksena sa pamamagitan ng isang hiwalay na Canvas, at pagkatapos ang handa na Bitmap ay ipapakita sa onDraw() sa pamamagitan ng drawBitmap(). Ito ay nagpapahintulot na i-update ang komplikadong graphics nang hindi ganap na iredraw ang bawat frame.

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)

    // I-render ang eksena nang isang beses
    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 ay ginagamit para sa pagbuo ng mga komplikadong contour: Bezier curves (quadTo, cubicTo), arko (arcTo), linya (lineTo). Ang Path ay maaaring sarado (close()) para sa mga punong hugis o bukas para sa mga linya. Ang mga pangunahing method na drawPath() ay pinagsasama ang Path at Paint para sa huling pagguhit.

Pag-optimize ng pagguhit ng Canvas

Ang performance ng pagguhit ng Canvas ay direktang nakakaapekto sa FPS ng application. Mga pangunahing problema: sobrang alokasyon sa onDraw(), madalas na invalidate() at hindi optimal na paggamit ng Hardware Acceleration.

Gumawa ng mga object sa labas ng onDraw()

Ang Paint, Path, Rect, RectF at iba pang mga object ay dapat gawin nang isang beses sa initializer o setup() method. Bawat alokasyon sa onDraw() ay nagbibigay ng trabaho sa garbage collector, na humahantong sa micro-lag. Exception — static o companion object para sa mga immutable object.

Gamitin ang clipRect() para sa paglilimita ng lugar

Kung ang malaking bahagi ng View ay nakatago sa labas ng nakikitang lugar (hal. sa ScrollView), gamitin ang canvas.clipRect() para limitahan ang pagguhit. Ang Hardware Acceleration sa kasong ito ay nag-o-optimize ng pag-clip ng mga hindi nakikitang pixel.

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

    // I-clip sa nakikitang lugar
    canvas.save()
    canvas.clipRect(scrollX, scrollY, scrollX + width, scrollY + height)

    // I-render ang malaking eksena
    renderScene(canvas)
    canvas.restore()
}

Gamitin ang View.setLayerType() na may LAYER_TYPE_HARDWARE para sa View na may komplikadong Canvas graphics na bihirang i-update. Para sa madalas na ina-update na animasyon, gamitin ang LAYER_TYPE_NONE upang maiwasan ang mahal na pag-update ng hardware layer. Mag-profile sa pamamagitan ng GPU Profile Rendering at Android Studio Profiler.

Mga Madalas Itanong

Maaari bang gumawa ng Canvas nang walang View?

Oo, maaaring gumawa ng Canvas(Bitmap) — constructor na tumatanggap ng Bitmap. Ito ay ginagamit para sa offscreen-rendering: gumuhit ka sa Bitmap, pagkatapos ay ipapakita ito sa pamamagitan ng drawBitmap(). Ang Canvas ay maaari ring gawin mula sa Surface (para sa SurfaceView) o sa pamamagitan ng Picture.

Ano ang pagkakaiba ng Canvas at SurfaceView?

Canvas — ay API para sa pagguhit sa View sa UI thread. SurfaceView — ay isang hiwalay na Surface na maaaring i-update mula sa background thread sa pamamagitan ng sarili nitong Canvas (lockCanvas() / unlockCanvasAndPost()). Ang SurfaceView ay mas gusto para sa mga laro at video.

Bakit hindi gumuhit ang Canvas pagkatapos ng transformasyon?

Ang pinakakaraniwang dahilan ay hindi balanseng save() at restore(). Kung pagkatapos ng transformasyon (translate, rotate) ay hindi tinawag ang restore(), ang Canvas ay mananatili sa nabagong coordinate system, at ang mga susunod na elemento ay iguguhit na may paglipat. Suriin ang mga pares ng save()/restore().

Paano gumuhit ng teksto sa gitna ng Canvas?

Gamitin ang Paint.setTextAlign(Paint.Align.CENTER) para sa horizontal alignment at Paint.getTextBounds() o Paint.descent() / ascent() para sa vertical. Pag-central: canvas.drawText(text, centerX, centerY - (ascent + descent) / 2, paint).

Sinusuportahan ba ng Canvas ang animasyon?

Ang Canvas mismo ay hindi nag-a-animate — ito ay gumuguhit lamang ng kasalukuyang estado. Ang animasyon ay nakakamit sa pamamagitan ng sunod-sunod na tawag sa invalidate() (o postInvalidateOnAnimation()), bawat oras ay gumuguhit ng bagong frame sa onDraw(). Para sa smooth na animasyon, gamitin ang ValueAnimator o Choreographer para sa sync sa Vsync.

Buod

  • Canvas — sentral na 2D drawing class sa Android, nagbibigay ng draw* method para sa pagguhit ng primitives, teksto at mga larawan
  • Paint — tumutukoy ng visual style (kulay, kapal, fill, shader); ginagawa nang isang beses at ginagamit muli
  • save() / restore() — pamamahala ng stack ng transformasyon; bawat transformasyon ay dapat nasa save/restore pair
  • Path — pagbuo ng arbitraryong contour at Bezier curves para sa komplikadong vector graphics
  • Offscreen Bitmap — technique ng pag-cache ng komplikadong eksena sa pamamagitan ng Canvas(Bitmap) para mabawasan ang load ng onDraw()
  • Hardware Acceleration — GPU acceleration para sa Canvas mula noong Android 3.0, nagpapataw ng limitasyon sa ilang operasyon (clipPath)
  • Profil — GPU Profile Rendering at Android Studio Profiler ay kinakailangan para sa paghahanap ng mga bottleneck sa onDraw()

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din