Android-da Canvas: bu nima, Canvas klassi va draw metodlari

Muallif: IT Sectr Nashr etilgan: 2026-07-21 O'qish vaqti: 7 daq

Android-da Canvas — android.graphics paketidagi View-da 2D chizish uchun API ta'minlovchi sinf. Canvas xuddi tuval kabi ishlaydi, unda dasturchi turli draw* metodlari yordamida geometrik shakllar, matn, tasvirlar va yo'llarni chizadi. Android Developers Documentation (2025) ma'lumotiga ko'ra, Canvas Android-da maxsus chizish uchun asosiy vositadir va uslublar va ranglarni belgilash uchun Paint sinfi bilan birga ishlatiladi. Har bir onDraw() chaqiruvi view-ning bitmap bufferi bilan bog'langan tayyor Canvas namunasini oladi.

Asosiy ma'lumotlar

  • Canvas — Android-da 2D chizish uchun sinf, drawRect, drawCircle, drawText, drawBitmap va boshqa metodlarni ta'minlaydi
  • Paint — chizish uslubini belgilaydigan sinf: rang, qalinlik, to'ldirish, effektlar (soya, gradient)
  • onDraw(Canvas) — olingan Canvas orqali barcha chizish sodir bo'ladigan View metodi
  • Canvas.save() va restore() — koordinatalar tizimining ichma-ich o'zgartirishlari uchun transformatsiyalar stekini boshqarish
  • Path — ixtiyoriy konturlar va egri chiziqlar qurish uchun sinf, drawPath(Path, Paint) ga uzatiladi

Android-da Canvas nima

Canvas — Android-da markaziy 2D grafik sinfi bo'lib, tekislikda chizish uchun metodlarni ta'minlaydi. Har bir Canvas Bitmap bilan bog'langan — chizish operatsiyalari natijalari yoziladigan xotira maydoni. View qayta chizilganda, tizim onDraw()-ga ushbu View-ning bufferi bilan bog'langan Canvas-ni uzatadi.

Canvas koordinatalar tizimida ishlaydi, bunda (0,0) yuqori chap burchak, X o'qi o'ngga, Y o'qi pastga ketadi. Barcha chizish operatsiyalari Canvas-ning joriy holatidan, jumladan transformatsiya matritsasi, kesish maydoni (clip) va Paint uslubidan foydalanadi. Android Documentation (2025) ma'lumotiga ko'ra, Canvas API turli grafik primitivlar uchun 30 dan ortiq draw* metodini o'z ichiga oladi.

Canvas va Hardware Acceleration

Android 3.0 (API 11) dan boshlab Canvas DisplayList orqali apparat tezlashtirishni qo'llab-quvvatlaydi. Tezlashtirilgan rejimda Canvas operatsiyalari DisplayList-ga yoziladi va keyin GPU-da bajariladi. Bu ishlashni sezilarli darajada oshiradi, lekin cheklovlar qo'yadi: ba'zi Canvas operatsiyalari (Path bo'lmagan klip bilan clipPath) tezlashtirilgan rejimda qo'llab-quvvatlanmaydi.

Canvas-ning asosiy chizish metodlari

Canvas asosiy primitivlarni chizish uchun metodlar to'plamini ta'minlaydi. Har bir metod geometrik parametrlar va vizual uslubni belgilaydigan Paint obyektini qabul qiladi.

MetodMaqsadMisol
drawRect()To'rtburchak chizishcanvas.drawRect(10f, 10f, 100f, 100f, paint)
drawCircle()Doira chizishcanvas.drawCircle(50f, 50f, 30f, paint)
drawLine()Chiziq chizishcanvas.drawLine(0f, 0f, 100f, 100f, paint)
drawText()Matn chizishcanvas.drawText("Hello", 10f, 20f, paint)
drawBitmap()Tasvir chizishcanvas.drawBitmap(bitmap, 0f, 0f, paint)
drawPath()Ixtiyoriy yo'l chizishcanvas.drawPath(path, paint)
drawOval()Oval chizishcanvas.drawOval(rectF, paint)
drawArc()Yoy yoki sektor chizishcanvas.drawArc(rectF, 0f, 90f, true, paint)

Har bir metod istalgan tartibda chaqirilishi mumkin — Canvas chaqiruvlar tartibida chizadi, yangi elementlarni oldingilari ustiga qo'yadi. Murakkab kompozitsiyalar uchun Canvas holatini saqlash va tiklash bilan ko'p qatlamli chizish texnikasi qo'llaniladi.

Paint sinfi: uslublar va effektlarni sozlash

Paint — Canvas qanday chizishini belgilaydigan sinf. Paint bo'lmasa, Canvas metodlari foydasiz — u rang, chiziq qalinligi, to'ldirish uslubi, matn o'lchami, effektlar (soya, gradient, xiralash) va aralashtirish rejimini belgilaydi.

Paint-ning asosiy xususiyatlari: color (rang), style (FILL, STROKE yoki FILL_AND_STROKE), strokeWidth (chiziq qalinligi), textSize (matn o'lchami), isAntiAlias (tekislash), shader (gradient yoki tasvir). Paint obyektini yaratish qimmat operatsiya, shuning uchun uni bir marta yaratib, qayta ishlatish kerak.

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

Ushbu misolda ikkita Paint ishlatiladi: biri doirani binafsha rang bilan to'ldirish uchun, ikkinchisi oq kontur uchun. Fill va stroke ga bo'lish — obyektlarni qayta yaratmasdan tashqi ko'rinishni moslashuvchan boshqarish imkonini beradigan standart amaliyotdir.

Shader va gradientlar

Gradient to'ldirishlar uchun Paint Shader qabul qiladi — LinearGradient, RadialGradient, SweepGradient pastki sinflari. Shader setShader() metodi orqali Paint-ga biriktiriladi va rangning chizish maydonida qanday o'zgarishini belgilaydi.

Canvas transformatsiyalari: translate, rotate, scale

Canvas koordinatalar tizimining matritsali o'zgartirishlarini qo'llab-quvvatlaydi: translate() (siljitish), rotate() (aylantirish), scale() (masshtablash) va skew() (qiyshatish). Transformatsiyalar yig'iladi: har bir keyingi chaqiruv avvalgilariga qo'llaniladi.

Transformatsiyalar stekini boshqarish save() va restore() orqali amalga oshiriladi. save() Canvas-ning joriy holatini (matritsa, clip) stekda saqlaydi, restore() oxirgi saqlangan holatni tiklaydi. save() va restore() o'rtasida ichma-ich transformatsiyalar bo'lishi mumkin.

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

    canvas.save() // Boshlang'ich holatni saqlash
    canvas.translate(100f, 100f) // Koordinata boshini siljitish

    // Birinchi kvadrat
    canvas.drawRect(0f, 0f, 50f, 50f, fillPaint)

    canvas.save() // Siljitishdan keyin saqlash
    canvas.rotate(45f, 25f, 25f) // Kvadrat markazi atrofida aylantirish

    // Aylantirilgan kvadrat
    canvas.drawRect(0f, 0f, 50f, 50f, strokePaint)
    canvas.restore() // Aylantirishdan keyin tiklash

    canvas.restore() // Boshlang'ich holatni tiklash
}

Har doim transformatsiyalarni boshlashdan oldin save() dan foydalaning va tugatgandan keyin restore() ni chaqiring. Muvozanatsiz save/restore matritsaning yig'ilishiga va keyingi elementlarning noto'g'ri chizilishiga olib keladi.

Murakkab grafikalar uchun Bitmap va Path bilan Canvas

Murakkab grafikalar uchun Canvas Bitmap va Path bilan birlashtiriladi. Bitmap tasvirlarni yuklash va renderlangan kadrlarni keshlash uchun ishlatiladi. Path — ixtiyoriy Bezier egri chiziqlari, ko'pburchaklar va murakkab konturlar qurish uchun.

Offscreen Bitmap buferi

Offscreen-rendering texnikasi: Bitmap yaratiladi, unda alohida Canvas orqali murakkab sahna chiziladi va tayyor Bitmap onDraw()-da drawBitmap() orqali ko'rsatiladi. Bu har bir kadrda to'liq qayta chizmasdan murakkab grafikani yangilash imkonini beradi.

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)

    // Sahnani bir marta renderlash
    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 murakkab konturlar qurish uchun ishlatiladi: Bezier egri chiziqlari (quadTo, cubicTo), yoylar (arcTo), chiziqlar (lineTo). Path to'ldirilgan shakllar uchun yopiq (close()) yoki chiziqlar uchun ochiq bo'lishi mumkin. drawPath() asosiy metodlari yakuniy chizish uchun Path va Paint-ni birlashtiradi.

Canvas chizishni optimallashtirish

Canvas chizish samaradorligi to'g'ridan-to'g'ri ilovaning FPS-iga ta'sir qiladi. Asosiy muammolar: onDraw()-da ortiqcha alokatsiyalar, tez-tez invalidate() va apparat tezlashtirishdan optimal foydalanmaslik.

Obyektlarni onDraw() tashqarisida yarating

Paint, Path, Rect, RectF va boshqa obyektlar bir marta inizializatorda yoki setup() metodida yaratilishi kerak. onDraw()-dagi har bir alokatsiya garbage collector-ni yuklaydi, bu esa mikro-laglarga olib keladi. Istisno — immutable obyektlar uchun static yoki companion object.

Maydonni cheklash uchun clipRect() dan foydalaning

Agar View-ning katta qismi ko'rinadigan maydondan tashqarida yashirin bo'lsa (masalan, ScrollView-da), chizishni cheklash uchun canvas.clipRect() dan foydalaning. Apparat tezlashtirish bu holda ko'rinmaydigan piksellarni kesishni qo'shimcha optimallashtiradi.

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

    // Ko'rinadigan maydonga kesish
    canvas.save()
    canvas.clipRect(scrollX, scrollY, scrollX + width, scrollY + height)

    // Katta sahnani renderlash
    renderScene(canvas)
    canvas.restore()
}

Kamdan-kam yangilanadigan murakkab Canvas grafikasi bo'lgan View uchun View.setLayerType() ni LAYER_TYPE_HARDWARE bilan ishlating. Tez-tez yangilanadigan animatsiyalar uchun LAYER_TYPE_NONE dan foydalaning, apparat qatlamining qimmat yangilanishidan qochish uchun. GPU Profile Rendering va Android Studio Profiler orqali profiling qiling.

Ko'p beriladigan savollar

Canvas-ni Viewsiz yaratish mumkinmi?

Ha, Canvas(Bitmap) — Bitmap qabul qiluvchi konstruktor yaratish mumkin. Bu offscreen-rendering uchun ishlatiladi: Bitmap ustida chizasiz, keyin uni drawBitmap() orqali ko'rsatasiz. Canvas shuningdek Surface-dan (SurfaceView uchun) yoki Picture orqali yaratilishi mumkin.

Canvas-ning SurfaceView-dan farqi nimada?

Canvas — UI thread-da View-da chizish uchun API. SurfaceView — o'z Canvas-i (lockCanvas() / unlockCanvasAndPost()) orqali fon thread-dan yangilanishi mumkin bo'lgan alohida Surface. SurfaceView o'yinlar va video uchun afzal.

Nega Canvas transformatsiyadan keyin chizmaydi?

Eng keng tarqalgan sabab — muvozanatsiz save() va restore(). Agar transformatsiyadan (translate, rotate) keyin restore() chaqirilmasa, Canvas o'zgartirilgan koordinatalar tizimida qoladi va keyingi elementlar siljish bilan chiziladi. save()/restore() juftliklarini tekshiring.

Canvas markazida matnni qanday chizish mumkin?

Gorizontal markazlashtirish uchun Paint.setTextAlign(Paint.Align.CENTER) va vertikal uchun Paint.getTextBounds() yoki Paint.descent() / ascent() dan foydalaning. Markazlashtirish: canvas.drawText(text, centerX, centerY - (ascent + descent) / 2, paint).

Canvas animatsiyani qo'llab-quvvatlaydimi?

Canvas o'zi animatsiya qilmaydi — u faqat joriy holatni chizadi. Animatsiya ketma-ket invalidate() (yoki postInvalidateOnAnimation()) chaqiruvlari orqali erishiladi, har safar onDraw()-da yangi kadr chiziladi. Silliq animatsiyalar uchun Vsync bilan sinxronizatsiya uchun ValueAnimator yoki Choreographer dan foydalaning.

Xulosa

  • Canvas — Android-da markaziy 2D chizish sinfi, primitivlar, matn va tasvirlarni chizish uchun draw* metodlarini ta'minlaydi
  • Paint — vizual uslubni belgilaydi (rang, qalinlik, to'ldirish, shaderlar); bir marta yaratiladi va qayta ishlatiladi
  • save() / restore() — transformatsiyalar stekini boshqarish; har bir transformatsiya save/restore juftligida bo'lishi kerak
  • Path — murakkab vektor grafikasi uchun ixtiyoriy konturlar va Bezier egri chiziqlarini qurish
  • Offscreen Bitmap — Canvas(Bitmap) orqali murakkab sahnalarni keshlash texnikasi, onDraw() yukini kamaytiradi
  • Apparat tezlashtirish — Android 3.0 dan Canvas uchun GPU tezlashtirish, ba'zi operatsiyalarga cheklovlar qo'yadi (clipPath)
  • Profiling — GPU Profile Rendering va Android Studio Profiler onDraw()-dagi tor joylarni topish uchun majburiy

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing