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 — 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.
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.
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.
| Method | Layunin | Halimbawa |
|---|---|---|
| drawRect() | Pagguhit ng parihaba | canvas.drawRect(10f, 10f, 100f, 100f, paint) |
| drawCircle() | Pagguhit ng bilog | canvas.drawCircle(50f, 50f, 30f, paint) |
| drawLine() | Pagguhit ng linya | canvas.drawLine(0f, 0f, 100f, 100f, paint) |
| drawText() | Pagguhit ng teksto | canvas.drawText("Hello", 10f, 20f, paint) |
| drawBitmap() | Pagguhit ng larawan | canvas.drawBitmap(bitmap, 0f, 0f, paint) |
| drawPath() | Pagguhit ng arbitraryong landas | canvas.drawPath(path, paint) |
| drawOval() | Pagguhit ng obalo | canvas.drawOval(rectF, paint) |
| drawArc() | Pagguhit ng arko o sektor | canvas.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 — 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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().
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).
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
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.
Basahin din