CustomPainter — Flutter SDK dan mavhum sinf bo'lib, dasturchilarga Canvas-da maxsus 2D grafikasini chizish ustidan to'liq nazorat beradi. Dasturchi CustomPainter ost sinfini yaratadi va ikkita majburiy metodni amalga oshiradi: paint(Canvas, Size) va shouldRepaint(covariant CustomPainter oldDelegate). Flutter API Documentation (2026) ma'lumotlariga ko'ra, CustomPainter CustomPaint vidjeti bilan birgalikda ishlatiladi, u har bir animatsiya kadrida yoki holat o'zgarishida chizishni CustomPainter obyektiga topshiradi.
Asosiy fikrlar
CustomPainter — Flutter-da ixtiyoriy 2D grafikasini amalga oshirish uchun asosiy sinfdir. U Android-dagi onDraw-ni bekor qilish yondashuvini almashtiradi va yanada moslashuvchan hamda deklarativ chizish modelini taqdim etadi. Dasturchi CustomPainter ost sinfini yaratadi, paint metodini bekor qiladi, unda Canvas va Size oladi va Canvas-da barcha chizish operatsiyalarini bajaradi. CustomPaint vidjeti paint chaqiruvini boshqaradi va natijani vidjetlar daraxtiga integratsiya qiladi.
CustomPainter va to'g'ridan-to'g'ri Canvas orqali chizish o'rtasidagi asosiy farq — chizish mantig'ini (paint) va qayta chizish tetikleyicisini (shouldRepaint) ajratishdir. Flutter tizimi ota vidjet har o'zgarganda shouldRepaint-ni chaqiradi. shouldRepaint false qaytarsa, paint chaqirilmaydi, bu resurslarni tejaydi. Bu mexanizm RenderObject-dagi shouldRebuild-ga o'xshaydi va Flutter arxitekturasining uch daraxti (Widget, Element, RenderObject) qismidir.
CustomPaint — painter (fon qatlami) va foregroundPainter (old qatlam) parametrlarini qabul qiladigan vidjetdir. Ikkala parametr CustomPainter obyektlarini qabul qiladi. Fon painter CustomPaint ning bola vidjetidan oldin chizadi, foregroundPainter esa undan keyin. Bu CustomPaint-ni dekorativ fon yoki qoplama bilan konteyner sifatida ishlatishga imkon beradi, oddiy vidjetlarni ichiga joylashtirish imkoniyatini yo'qotmagan holda.
Canvas — Flutter-da chizish uchun markaziy obyekt bo'lib, grafik sirtni inkapsulyatsiya qiladi. Taxminan 40 ta chizish metodini taqdim etadi: drawLine, drawCircle, drawRect, drawPath, drawArc, drawImage, drawPicture, drawPoints va boshqalar. Flutter-dagi Canvas Android Canvas-dagi o'xshash sinfga mos keladi, lekin Dart va Flutter Engine arxitekturasiga moslashtirilgan. Canvas koordinatalar tizimida ishlaydi, bu erda boshlanish (0, 0) yuqori chap burchakdir.
Paint — paint() metodi bilan adashtirmang — chizish uslubini belgilaydigan sinf: rang (color), chiziq qalinligi (strokeWidth), uslub (style: fill yoki stroke), shaffoflik, aralashtirish rejimi (blendMode) va tekislash maskasi. Paint chizishdan oldin sozlanadi va Canvas metodlariga uzatiladi. Muhim: Paint o'zgartiriladigan obyekt, lekin uni bir marta yaratib qayta ishlatish, faqat kerakli parametrlarni o'zgartirish tavsiya etiladi.
| Canvas metodi | Maqsad | Parametrlar |
|---|---|---|
| drawCircle | Doira chizish | Offset center, double radius, Paint paint |
| drawLine | Chiziq chizish | Offset p1, Offset p2, Paint paint |
| drawRect | To'rtburchak chizish | Rect rect, Paint paint |
| drawPath | Ixtiyoriy kontur chizish | Path path, Paint paint |
| drawArc | Yoy yoki sektor chizish | Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint |
| drawRRect | Yumaloq burchakli to'rtburchak | RRect rrect, Paint paint |
| drawOval | Oval chizish | Rect rect, Paint paint |
| drawImage | Image dan rasm chizish | Image image, Offset p, Paint paint |
Canvas koordinatalar tizimining transformatsiyalarini qo'llab-quvvatlaydi: translate(double dx, double dy) koordinatalar boshini siljitadi; rotate(double radians) tizimni aylantiradi; scale(double sx, double sy) masshtablaydi; skew(double sx, double sy) egadi. Transformatsiyadan oldin Canvas holatini save() orqali saqlash, tugagandan keyin esa restore() orqali tiklash tavsiya etiladi. Bu keyingi paint chaqiruvlarida transformatsiyalarning to'planishini oldini oladi.
paint(Canvas canvas, Size size) — barcha chizish mantig'i amalga oshiriladigan majburiy metod. canvas parametri — chizish uchun grafik sirt. size parametri — chizish uchun ajratilgan maydonning o'lchami (kenglik va balandlik mantiqiy piksellarda). Canvas oldindan sozlanganki, koordinatalar boshi (0,0) chizish maydonining yuqori chap burchagiga mos keladi. Barcha koordinatalar shu boshlanishga nisbatan belgilanadi.
shouldRepaint(covariant CustomPainter oldDelegate) — qayta chizish chastotasini optimallashtiradigan majburiy metod. Flutter CustomPainter-ga ta'sir qiladigan vidjetlar daraxtining har bir yangilanishida shouldRepaint-ni chaqiradi. Agar metod false qaytarsa, allaqachon chizilgan rasm haqiqiy hisoblanadi va paint chaqirilmaydi. Oddiy amalga oshirish: return oldDelegate.someField != someField — qayta chizish zaruriyatini aniqlash uchun eski va yangi painter maydonlarini solishtirish.
Animatsiyalangan yoki doimiy o'zgaruvchan tasvirlar uchun (soatlar, yuklanish ko'rsatkichlari, grafiklar) shouldRepaint har bir holat o'zgarishida true qaytarishi kerak. Agar obyekt statik bo'lsa (logo, ikonka, fon), shouldRepaint birinchi chizishdan keyin false qaytaradi. Flutter paint natijasini avtomatik keshga oladi va faqat o'lcham, shaffoflik o'zgarganda yoki shouldRepaint chaqirilganda qayta chizadi.
GaugePainter yarataylik — animatsiyalangan to'ldirish bilan maxsus aylana ko'rsatkich. CustomPainter joriy qiymatni (progress 0.0 dan 1.0 gacha) qabul qiladi va gradient bilan yoy chizadi. shouldRepaint metodida optimallashtirish uchun progress qiymati solishtiriladi. CustomPaint vidjetlar daraxtiga chizish maydonini cheklash uchun size parametri bilan joylashtiriladi.
class GaugePainter extends CustomPainter {
final double progress;
final Color startColor;
final Color endColor;
GaugePainter({
required this.progress,
this.startColor = Colors.blue,
this.endColor = Colors.cyan,
});
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2,
size.height / 2);
final radius = center.dx - 12;
final bgPaint = Paint()
..color = Colors.grey.withOpacity(0.3)
..style = PaintingStyle.stroke
..strokeWidth = 16
..strokeCap = StrokeCap.round;
final progressPaint = Paint()
..shader = LinearGradient(
colors: [startColor, endColor],
).createShader(
Rect.fromCircle(
center, radius))
..style = PaintingStyle.stroke
..strokeWidth = 16
..strokeCap = StrokeCap.round;
canvas.drawCircle(center, radius, bgPaint);
canvas.drawArc(
Rect.fromCircle(center, radius),
-math.pi / 2,
2 * math.pi * progress,
false, progressPaint);
}
@override
bool shouldRepaint(
GaugePainter oldDelegate) {
return oldDelegate.progress != progress;
}
}
Misol Path yordamida to'lqinli grafik chizadi. Path chiziqlar, Bezier egri chiziqlari va yoylardan ixtiyoriy konturlar qurishga imkon beradi. Kontur qurilgandan keyin rang bilan to'ldiriladi yoki chiziq bilan hoshiyalanadi. Misolda grafik to'lqin shaklini taqlid qiladigan nuqtalar massivi asosida quriladi.
class WavePainter extends CustomPainter {
final List<double> values;
WavePainter({required this.values});
@override
void paint(Canvas canvas, Size size) {
final path = Path();
final dx = size.width /
(values.length - 1);
path.moveTo(0, size.height);
for (var i = 0; i < values.length; i++) {
final x = i * dx;
final y = size.height *
(1 - values[i]);
path.lineTo(x, y);
}
path.lineTo(size.width, size.height);
path.close();
final fillPaint = Paint()
..color = Colors.blue.withOpacity(0.3)
..style = PaintingStyle.fill;
canvas.drawPath(path, fillPaint);
}
@override
bool shouldRepaint(
WavePainter oldDelegate) {
return oldDelegate.values != values;
}
}
painter (fon) CustomPaint ning bola vidjetidan oldin chizadi. CustomPaint bola vidjetiga ega bo'lsa (child parametri), fon painter uning ostida ko'rsatiladi. Bu bezak uchun mos: progress chiziqlari, fon naqshlari, suv belgilari. foregroundPainter bola vidjetdan keyin, ya'ni uning ustida chizadi. Qoplamalar uchun ishlatiladi: yaltiroqlar, maskalar, o'lchov chizg'ichlari, annotatsiyalar.
Farq painter va foregroundPainter o'rtasida Z-order uchun juda muhim. Agar kontent orqasida biror narsa chizish kerak bo'lsa — painter dan foydalaning. Agar kontent ustida bo'lsa — foregroundPainter. Ba'zi hollarda ikkala painter ni bir vaqtda ishlatish mumkin: fon painter orqali, yorliq-qoplama foregroundPainter orqali. Bu turli grafik qatlamlarning mantig'ini ikkita alohida CustomPainter sinfiga ajratishga imkon beradi.
size parametri paint metodida ikkala painter uchun bir xil va CustomPaint uchun ajratilgan maydonning o'lchami bilan aniqlanadi. O'lcham CustomPaint dagi size parametri orqali aniq yoki ota konteyner orqali noaniq tarzda belgilanishi mumkin. size Size.zero ga teng bo'lsa, paint chaqirilmaydi — Flutter nol maydon uchun chizishni o'tkazib yuboradi. Bu xatti-harakat elementning animatsiyalangan paydo bo'lishida hisobga olinishi kerak.
Asosiy qoida CustomPainter ishlashi — paint metodi ichida obyektlar yaratmaslik. Canvas, Paint, Path, Rect, Offset va boshqa chizish obyektlari CustomPainter konstruktorida yaratilishi yoki keshga olinishi kerak. paint ichida obyekt yaratish har bir kadrda alokatsiyalarga olib keladi, bu sekundiga 60 kadrda tez-tez axlat yig'ish va animatsiyaning siltanishiga (jank) sabab bo'ladi.
Path ni keshga olish takrorlanuvchi murakkab konturlarni chizishni sezilarli darajada tezlashtiradi. Agar kontur kadrlar orasida o'zgarmasa (masalan, fon tori), Path-ni bir marta yarating va ko'p marta ishlating. RepaintBoundary — CustomPainter-ni yuqoridagi vidjetlar daraxti o'zgarganda qayta chizilishidan himoya qiladigan o'rovchi vidjet. CustomPainter statik bo'lsa, uni izolyatsiya uchun RepaintBoundary ga o'rang.
Tez-tez qayta chiziladigan animatsiyalangan CustomPainter uchun Ticker yoki AnimationController dan foydalaning, shouldRepaint animatsiyalangan qiymat o'zgarganda true qaytarsin. Optimal ravishda shouldRepaint-da animatsiyalangan maydonni solishtiring, har bir kadrda keraksiz qayta chizmang. Murakkab gradientlar uchun Rect keshi: gradient ranglarni o'zgartirmasa, Paint.shader orqali Shader-ni keshga olish mumkin.
Tez-tez beriladigan savollar
CustomPainter — Canvas-da nima va qanday chizilishini belgilaydigan shartnoma sinfi. Canvas — metodlarni taqdim etadigan (drawCircle, drawLine va boshqalar) chizish obyektining o'zi. CustomPainter Canvas-ni paint metodi orqali oladi va undan foydalanishni boshqaradi. Bitta Canvas turli vaqtlarda turli CustomPainter tomonidan ishlatilishi mumkin.
Yo'q, CustomPainter CustomPaint siz ma'noga ega emas. CustomPaint — CustomPainter ning paint metodini chaqiradigan va natijani ekranda ko'rsatadigan vidjet. CustomPaint siz Canvas yaratilmaydi va paint bajarilmaydi. Biroq, Canvas bilan o'zingizning RenderObject-ingizni amalga oshirishingiz mumkin, ammo bu pastroq darajali yondashuv.
AnimationController dan Ticker bilan foydalaning, animatsiyalangan qiymatni CustomPainter-ga konstruktor parametrlari orqali uzating. Qiymat o'zgarganda CustomPaint ni o'z ichiga olgan vidjetda setState() ni chaqiring, bu shouldRepaint-ni tetiklaydi. shouldRepaint true qaytarsa, tizim animatsiyaning yangi kadri uchun paint ni chaqiradi.
Sabab deyarli har doim false qaytaradigan shouldRepaint dir. oldDelegate maydonlarining yangi qiymatlar bilan to'g'ri solishtirilayotganini tekshiring. Agar o'zgartiriladigan obyekt ishlatilsa, shouldRepaint o'zgarishlarni sezmasligi mumkin, chunki obyektga havola bir xil qoladi. To'g'ri solishtirish uchun == yoki o'zgarmas obyektlardan foydalaning.
Ha, CustomPainter murakkab ro'yxatlarda maxsus bezaklarni chizish uchun ishlatiladi. Biroq, elementlarni qayta tartiblashda ListView ichidagi RepaintBoundary har bir elementning chizilishini keshga oladi. CustomPainter engil bo'lishi va paint ichida og'ir operatsiyalarni o'z ichiga olmasligi kerak, bu sudrab olish animatsiyasini sekinlashtirmasligi uchun.
Xulosa
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.