Android-də Canvas: bu nədir, Canvas sinfi və draw metodları

Müəllif: IT Sectr Dərc olunub: 2026-07-21 Oxuma vaxtı: 7 dəq

Android-də Canvas — android.graphics paketindən olan, View-də 2D çəkmə üçün API təmin edən sinifdir. Canvas kətan kimi işləyir, üzərində tərtibatçı müxtəlif draw* metodları vasitəsilə həndəsi fiqurlar, mətn, şəkillər və yollar çəkir. Android Developers Documentation (2025) məlumatına görə, Canvas Android-də xüsusi çəkmə üçün əsas vasitədir və üslublar və rənglər təyin etmək üçün Paint sinfi ilə birlikdə istifadə olunur. Hər onDraw() çağırışı görünüşün bitmap buferi ilə əlaqəli hazır Canvas nümunəsi alır.

Əsas məqamlar

  • Canvas — Android-də 2D çəkmə üçün sinif, drawRect, drawCircle, drawText, drawBitmap və digər metodları təmin edir
  • Paint — çəkmə üslubunu təyin edən sinif: rəng, qalınlıq, doldurma, effektlər (kölgə, gradient)
  • onDraw(Canvas) — alınan Canvas vasitəsilə bütün çəkmənin baş verdiyi View metodu
  • Canvas.save() və restore() — koordinat sisteminin iç-içə çevrilmələri üçün transformasiya yığınının idarə edilməsi
  • Path — ixtiyari konturlar və əyrilər qurmaq üçün sinif, drawPath(Path, Paint)-ə ötürülür

Android-də Canvas nədir

Canvas — Android-də mərkəzi 2D qrafika sinfidir, müstəvidə çəkmə üçün metodlar təmin edir. Hər Canvas Bitmap ilə əlaqəlidir — çəkmə əməliyyatlarının nəticələrinin yazıldığı yaddaş sahəsi. View yenidən çəkildikdə, sistem onDraw()-a bu View-in buferi ilə artıq əlaqəli Canvas ötürür.

Canvas koordinat sistemində işləyir, burada (0,0) yuxarı sol küncdür, X oxu sağa, Y oxu aşağı gedir. Bütün çəkmə əməliyyatları Canvas-ın cari vəziyyətindən, o cümlədən transformasiya matrisi, kəsmə sahəsi (clip) və Paint üslubundan istifadə edir. Android Documentation (2025) məlumatına görə, Canvas API müxtəlif qrafik primitivlər üçün 30-dan çox draw* metodu daxildir.

Canvas və Hardware Acceleration

Android 3.0-dan (API 11) etibarən Canvas DisplayList vasitəsilə aparat sürətləndirilməsini dəstəkləyir. Sürətləndirilmiş rejimdə Canvas əməliyyatları DisplayList-ə yazılır və sonra GPU-da icra olunur. Bu, performansı əhəmiyyətli dərəcədə artırır, lakin məhdudiyyətlər qoyur: bəzi Canvas əməliyyatları (Path olmayan klip ilə clipPath) sürətləndirilmiş rejimdə dəstəklənmir.

Canvas-in çəkmə üçün əsas metodları

Canvas əsas primitivlərin çəkilməsi üçün metodlar dəsti təmin edir. Hər metod həndəsi parametrlər və vizual üslubu təyin edən Paint obyektini qəbul edir.

MetodMəqsədNümunə
drawRect()Düzbucaqlı çəkməkcanvas.drawRect(10f, 10f, 100f, 100f, paint)
drawCircle()Dairə çəkməkcanvas.drawCircle(50f, 50f, 30f, paint)
drawLine()Xətt çəkməkcanvas.drawLine(0f, 0f, 100f, 100f, paint)
drawText()Mətn çəkməkcanvas.drawText("Hello", 10f, 20f, paint)
drawBitmap()Şəkil çəkməkcanvas.drawBitmap(bitmap, 0f, 0f, paint)
drawPath()İxtiyari yol çəkməkcanvas.drawPath(path, paint)
drawOval()Oval çəkməkcanvas.drawOval(rectF, paint)
drawArc()Qövs və ya sektor çəkməkcanvas.drawArc(rectF, 0f, 90f, true, paint)

Hər metod istənilən ardıcıllıqla çağrıla bilər — Canvas çağırış sırası ilə çəkir, yeni elementləri əvvəlkilərin üzərinə qoyur. Mürəkkəb kompozisiyalar üçün Canvas vəziyyətinin saxlanması və bərpası ilə çoxqatlı çəkmə texnikası istifadə olunur.

Paint sinfi: üslub və effektlərin konfiqurasiyası

Paint — Canvas-ın necə çəkəcəyini təyin edən sinifdir. Paint olmadan Canvas metodları faydasızdır — o, rəng, xətt qalınlığı, doldurma üslubu, mətn ölçüsü, effektlər (kölgə, gradient, bulanıqlıq) və qarışdırma rejimini təyin edir.

Paint-in əsas xüsusiyyətləri: color (rəng), style (FILL, STROKE və ya FILL_AND_STROKE), strokeWidth (xətt qalınlığı), textSize (mətn ölçüsü), isAntiAlias (hamarlaşdırma), shader (gradient və ya şəkil). Paint obyektinin yaradılması bahalı əməliyyatdır, ona görə onu bir dəfə yaradıb təkrar istifadə etmək lazımdır.

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

Bu nümunədə iki Paint istifadə olunur: biri dairəni bənövşəyi rənglə doldurmaq üçün, ikincisi ağ kontur üçün. Fill və stroke bölgüsü — obyektləri yenidən yaratmadan görünüşü çevik idarə etməyə imkan verən standart təcrübədir.

Shader və gradientlər

Gradient doldurmalar üçün Paint Shader qəbul edir — LinearGradient, RadialGradient, SweepGradient alt sinifləri. Shader setShader() metodu vasitəsilə Paint-ə bağlanır və rəngin çəkmə sahəsində necə dəyişdiyini təyin edir.

Canvas transformasiyaları: translate, rotate, scale

Canvas koordinat sisteminin matris çevrilmələrini dəstəkləyir: translate() (yerdəyişmə), rotate() (fırlanma), scale() (miqyaslama) və skew() (əymə). Transformasiyalar yığılır: hər növbəti çağırış əvvəlkilərin üzərinə tətbiq olunur.

Transformasiya yığınının idarə edilməsi save()restore() vasitəsilə həyata keçirilir. save() Canvas-ın cari vəziyyətini (matris, clip) yığında saxlayır, restore() son saxlanmış vəziyyəti bərpa edir. save() və restore() arasında iç-içə transformasiyalar ola bilər.

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

    canvas.save() // İlkin vəziyyəti saxla
    canvas.translate(100f, 100f) // Mənşəyi yerdəyiş

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

    canvas.save() // Yerdəyişmədən sonra saxla
    canvas.rotate(45f, 25f, 25f) // Kvadrat mərkəzi ətrafında fırlat

    // Fırlanmış kvadrat
    canvas.drawRect(0f, 0f, 50f, 50f, strokePaint)
    canvas.restore() // Fırlanmadan sonra bərpa et

    canvas.restore() // İlkin vəziyyəti bərpa et
}

Həmişə transformasiyalara başlamazdan əvvəl save() istifadə edin və bitdikdən sonra restore() çağırın. Balanssız save/restore matrisin yığılmasına və sonrakı elementlərin səhv çəkilməsinə səbəb olur.

Mürəkkəb qrafika üçün Bitmap və Path ilə Canvas

Mürəkkəb qrafika üçün Canvas BitmapPath ilə birləşdirilir. Bitmap şəkilləri yükləmək və render edilmiş kadrları keşləmək üçün istifadə olunur. Path — ixtiyari Bezier əyriləri, çoxbucaqlılar və mürəkkəb konturlar qurmaq üçün.

Offscreen Bitmap buferi

Offscreen-rendering texnikası: Bitmap yaradılır, üzərində ayrıca Canvas vasitəsilə mürəkkəb səhnə çəkilir və hazır Bitmap onDraw()-da drawBitmap() ilə göstərilir. Bu, hər kadrda tam yenidən çəkmədən mürəkkəb qrafikanı yeniləməyə imkan verir.

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)

    // Səhnəni bir dəfə render et
    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 mürəkkəb konturlar qurmaq üçün istifadə olunur: Bezier əyriləri (quadTo, cubicTo), qövslər (arcTo), xətlər (lineTo). Path doldurulmuş fiqurlar üçün bağlı (close()) və ya xətlər üçün açıq ola bilər. drawPath() əsas metodları son çəkmə üçün Path və Paint-i birləşdirir.

Canvas çəkməsinin optimallaşdırılması

Canvas çəkməsinin performansı birbaşa tətbiqin FPS-nə təsir edir. Əsas problemlər: onDraw()-da həddindən artıq alokasiyalar, tez-tez invalidate() və Hardware Acceleration-dən optimal olmayan istifadə.

Obyektləri onDraw() xaricində yaradın

Paint, Path, Rect, RectF və digər obyektlər bir dəfə inisializatorda və ya setup() metodunda yaradılmalıdır. onDraw()-da hər alokasiya garbage collector-u yükləyir, bu da mikro-laglara səbəb olur. İstisna — immutable obyektlər üçün static və ya companion object.

Sahəni məhdudlaşdırmaq üçün clipRect() istifadə edin

View-in böyük hissəsi görünən sahədən kənarda gizlidirsə (məsələn, ScrollView-də), çəkməni məhdudlaşdırmaq üçün canvas.clipRect() istifadə edin. Bu halda Hardware Acceleration görünməyən piksellərin kəsilməsini əlavə olaraq optimallaşdırır.

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

    // Görünən sahəyə kəs
    canvas.save()
    canvas.clipRect(scrollX, scrollY, scrollX + width, scrollY + height)

    // Böyük səhnəni render et
    renderScene(canvas)
    canvas.restore()
}

Nadir hallarda yenilənən mürəkkəb Canvas qrafikası olan View üçün View.setLayerType() LAYER_TYPE_HARDWARE ilə istifadə edin. Tez-tez yenilənən animasiyalar üçün isə LAYER_TYPE_NONE istifadə edin ki, aparat qatının bahalı yenilənməsindən qaçın. GPU Profile RenderingAndroid Studio Profiler ilə profil edin.

Tez-tez verilən suallar

View olmadan Canvas yaratmaq mümkündürmü?

Bəli, Canvas(Bitmap) — Bitmap qəbul edən konstruktor yaratmaq olar. Bu, offscreen-rendering üçün istifadə olunur: Bitmap üzərində çəkirsiniz, sonra onu drawBitmap() vasitəsilə göstərirsiniz. Canvas həmçinin Surface-dən (SurfaceView üçün) və ya Picture vasitəsilə yaradıla bilər.

Canvas-ın SurfaceView-dən fərqi nədir?

Canvas — UI thread-də View-də çəkmə üçün API-dir. SurfaceView — öz Canvas-ı (lockCanvas() / unlockCanvasAndPost()) vasitəsilə fon thread-indən yenilənə bilən ayrıca Surface-dir. SurfaceView oyunlar və video üçün üstünlük təşkil edir.

Niyə Canvas transformasiyadan sonra çəkmir?

Ən çox rast gəlinən səbəb balanssız save()restore()-dur. Əgər transformasiyadan (translate, rotate) sonra restore() çağırılmasa, Canvas dəyişdirilmiş koordinat sistemində qalır və sonrakı elementlər yerdəyişmə ilə çəkilir. save()/restore() cütlərini yoxlayın.

Canvas mərkəzində mətni necə çəkmək olar?

Üfüqi mərkəzləşdirmə üçün Paint.setTextAlign(Paint.Align.CENTER) və şaquli üçün Paint.getTextBounds() və ya Paint.descent() / ascent() istifadə edin. Mərkəzləşdirmə: canvas.drawText(text, centerX, centerY - (ascent + descent) / 2, paint).

Canvas animasiyanı dəstəkləyirmi?

Canvas özü animasiya etmir — o, yalnız cari vəziyyəti çəkir. Animasiya ardıcıl invalidate() (və ya postInvalidateOnAnimation()) çağırışları vasitəsilə əldə edilir, hər dəfə onDraw()-da yeni kadr çəkilir. Hamar animasiyalar üçün Vsync ilə sinxronizasiya üçün ValueAnimator və ya Choreographer istifadə edin.

Nəticə

  • Canvas — Android-də mərkəzi 2D çəkmə sinfi, primitivləri, mətni və şəkilləri çəkmək üçün draw* metodları təmin edir
  • Paint — vizual üslubu təyin edir (rəng, qalınlıq, doldurma, şeyderlər); bir dəfə yaradılır və təkrar istifadə olunur
  • save() / restore() — transformasiya yığınının idarə edilməsi; hər transformasiya save/restore cütü olmalıdır
  • Path — mürəkkəb vektor qrafikası üçün ixtiyari konturlar və Bezier əyriləri qurmaq
  • Offscreen Bitmap — Canvas(Bitmap) vasitəsilə mürəkkəb səhnələrin keşlənməsi texnikası, onDraw() yükünü azaldır
  • Hardware Acceleration — Android 3.0-dan Canvas üçün GPU sürətləndirilməsi, bəzi əməliyyatlara məhdudiyyətlər qoyur (clipPath)
  • Profilinq — GPU Profile Rendering və Android Studio Profiler onDraw()-da dar boğazları tapmaq üçün məcburidir

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun