Maxsus ko'rinishlar har qanday mobil ilovaning noyob interfeysining asosidir. Mobil ilovalardagi maxsus ko'rinishlar standart komponentlarda mavjud bo'lmagan o'zingizning grafika, animatsiya va elementlaringizni yaratishga imkon beradi. Apple Developer, 2025 ma'lumotlariga ko'ra, drawRect iOS mobil ishlab chiqishida maxsus chizishning asosiy usuli bo'lib qolmoqda. Androidda, Canvas bilan onDraw bir xil rolni o'ynaydi, Flutterda esa — CustomPainter.
Asosiy fikrlar
Maxsus ko'rinishlar noyob grafika yaratish uchun standart chizish va o'lchash usullarini bekor qiluvchi foydalanuvchi tomonidan belgilangan interfeys komponentlaridir. Grafiklar, animatsiyalar, diagrammalar, maxsus chat elementlari va AR niqoblari — bu mobil ilovalarda maxsus ko'rinishlardan foydalanishning odatiy stsenariylari. Standart UI komponentlari (Button, TextView, Label) vazifalarning 80% ini qamrab oladi, ammo qolgan 20% mobil ishlab chiqishda chizish ustidan to'liq nazoratni talab qiladi. Mobil ishlab chiqishda chizish junior dasturchini senior dasturchidan ajratib turadigan mahoratdir.
Mobil ilovalardagi maxsus ko'rinishlar noyob 2D grafika, murakkab animatsiyalar, chartlar va ma'lumotlarni vizuallashtirish uchun zarur. Agar standart UIKit kerakli elementni taqdim etmasa — maxsus ko'rinish yaratiladi. Mobil ilovalarda, maxsus ko'rinishlar taraqqiyot chiziqlari, maxsus tugmalar, gradient to'ldirishlar, animatsiyalangan piktogrammalar va barmoq bilan chizish uchun kanvaslar uchun ishlatiladi. Ortiqcha ishlatmaslik muhim — oddiy uslublar uchun, Ko'rinish API si orqali standart komponentlarni sozlash kifoya.
iOSda, maxsus ko'rinishlar UIView dan meros olish va drawRect usulini bekor qilish orqali yaratiladi. drawRect birinchi renderda va har bir setNeedsDisplay() chaqiruvidan keyin chaqiriladi. drawRect ichida, dasturchi UIGraphicsGetCurrentContext() orqali CGContext oladi — chiziqlar, shakllar, gradientlar va matn uchun kanvas. Core Graphics (Quartz 2D) har bir piksel ustidan to'liq nazorat beruvchi past darajadagi CPU asosidagi render muhitidir. UIBezierPath qisqa sintaksis bilan yo'llar yaratish uchun qulay o'ramdir.
class CircleView: UIView {
private var fillColor: UIColor = .systemBlue
override func drawRect(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.setFillColor(fillColor.cgColor)
ctx.addEllipse(in: bounds.insetBy(dx: 4, dy: 4))
ctx.drawPath(using: .fill)
}
func updateColor(_ newColor: UIColor) {
fillColor = newColor
setNeedsDisplay()
}
}
Core Graphics barcha chizish operatsiyalari uchun CGContext — kanvasni taqdim etadi. CGGradient CGColorSpace (sRGB, Display P3) qo'llab-quvvatlashi bilan chiziqli va radial gradientlar yaratadi. Transformatsiyalar CGAffineTransform orqali amalga oshiriladi — aylantirish, masshtablash va siljitish uchun 3x3 matritsa. CGContextTranslateCTM, CGContextRotateCTM va CGContextScaleCTM koordinatalar tizimini o'zgartiradi. Core Graphics CPUda ishlaydi, shuning uchun murakkab grafika protsessorni yuklashi mumkin — GPU tezlashtirish uchun Metal dan foydalaning.
UIBezierPath CGPath ustidagi ob'ektga yo'naltirilgan o'ramdir. addArc(withCenter:radius:startAngle:endAngle:clockwise:) usuli yoylar va doiralar yaratadi, addCurve Bezier egri chiziqlarini yaratadi. Yo'llar addClip orqali birlashma, kesishma va ayirish operatsiyalarini qo'llab-quvvatlaydi. UIBezierPath maxsus niqoblar (maskView), kesish yo'llari va murakkab shakllar — yulduzlar, yuraklar, maxsus piktogrammalar uchun qulay.
Androidda, maxsus ko'rinish onDraw(Canvas) bekor qilinib View ni kengaytiradi. Canvas mobil ishlab chiqishdagi barcha chizish usullarini o'z ichiga oladi: drawCircle, drawRect, drawLine, drawText, drawBitmap, drawPath va drawRoundRect. Paint parametrlarni sozlaydi — rang, chiziq qalinligi, uslub (FILL, STROKE, FILL_AND_STROKE), tekislash (isAntiAlias) va matn o'lchami. onDraw har bir invalidate() da chaqiriladi va og'ir operatsiyalarni o'z ichiga olmasligi kerak — barcha hisob-kitoblar keshlanadi.
class CustomCircleView(context: Context, attrs: AttributeSet?)
: View(context, attrs) {
private val paint = Paint().apply {
style = Paint.Style.FILL
color = Color.BLUE
isAntiAlias = true
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
val radius = minOf(cx, cy) - 4f
canvas.drawCircle(cx, cy, radius, paint)
}
}
Androidda Path UIBezierPath ga teng: addCircle, addRect, addOval, lineTo, cubicTo va quadTo. PathMeasure yo'l uzunligini va istalgan nuqtadagi koordinatalarni hisoblaydi — ob'ektning yo'l bo'ylab harakatini animatsiya qilish uchun foydali. Animatsiyalar uchun, qayta chaqiruvda invalidate() bilan ValueAnimator ishlatiladi. Animator rang, radius, pozitsiyani o'zgartirishi mumkin — chizishga ta'sir qiluvchi har qanday xususiyat. Androiddagi maxsus ko'rinishlar XML orqali animatsiya uchun StateListDrawable va animated-vectorni ham qo'llab-quvvatlaydi.
Androidda gradientlar Shader orqali o'rnatiladi — LinearGradient, RadialGradient va SweepGradient. Shader paint.setShader(shader) orqali Paint ga tayinlanadi. LinearGradient ikki nuqta orasida ixtiyoriy rang pozitsiyalari bilan chiziqli gradient hosil qiladi. RadialGradient — markazdan chekkalarga radial. SweepGradient — markaziy nuqta atrofida konus shaklida. Shader.TileMode (CLAMP, REPEAT, MIRROR) maydon chegaralaridan tashqaridagi xatti-harakatni belgilaydi.
Flutter CustomPainter dan foydalanadi — paint(Canvas canvas, Size size) va shouldRepaint usullariga ega sinf. Flutterdagi Canvas Androiddagi kabi usullarni taqdim etadi: drawCircle, drawRect, drawLine, drawPath, drawParagraph va drawImage. Flutterdagi Paint rang, qalinlik, uslub va tekislashni sozlaydi. Flutter drawRect yoki onDraw dan foydalanmaydi — barcha chizish CustomPaint vidjetiga o'rnatilgan CustomPainter orqali amalga oshiriladi.
class CirclePainter extends CustomPainter {
final Color color;
CirclePainter({required this.color});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..style = PaintingStyle.fill
..isAntiAlias = true;
final radius = size.shortestSide / 2 - 4;
canvas.drawCircle(size.center(Offset.zero), radius, paint);
}
@override
bool shouldRepaint(CirclePainter oldDelegate) =>
oldDelegate.color != color;
}
shouldRepaint CustomPainterni qayta chizish kerakligini aniqlaydi. Faqat renderlashga ta'sir qiluvchi ma'lumotlar o'zgarganda true qaytaring — rang, o'lcham, chart ma'lumotlari. RepaintBoundary qayta chizishni alohida qatlamda izolyatsiya qiladi — kamdan-kam o'zgaradigan vidjetlar uchun foydalaning. Flutterda setNeedsDisplay yoki invalidate yo'q — qayta chizish setState yoki o'zgarishlarni tinglovchi ValueNotifier orqali tetiklanadi.
Flutter LinearGradient, RadialGradient va SweepGradientni qo'llab-quvvatlaydi — Androiddagi kabi bir xil turlar. Gradient createShader(Rect bounds) orqali Paint uchun Shader yaratadi. Transformatsiyalar canvas.rotate, canvas.scale, canvas.translate va canvas.skew orqali amalga oshiriladi. Flutter Transform vidjeti uchun 4x4 transformatsiya matritsasidan (Matrix4) foydalanadi. Flutterda chizish animatsiyalari CustomPainterni qayta chizish uchun setState bilan birgalikda AnimationController yordamida amalga oshiriladi.
Maxsus ko'rinishlarni to'g'ri o'lchash bashorat qilinadigan interfeys xatti-harakatining asosidir. iOSda, Ko'rinishning o'lchami sizeThatFits va intrinsicContentSize orqali aniqlanadi. sizeThatFits berilgan cheklovlar uchun eng maqbul o'lchamni qaytaradi. intrinsicContentSize — tashqi cheklovlarsiz tarkibning tabiiy o'lchami. Androidda, o'lchash MeasureSpec parametrlari (UNSPECIFIED, EXACTLY, AT_MOST) bilan onMeasure da amalga oshiriladi. Flutterda, o'lcham paint(Canvas, Size) ga uzatiladi va computeDryLayout yoki LayoutBuilder orqali hisoblanishi mumkin.
intrinsicContentSize CGSize qaytaradi — tarkibiga asoslangan Ko'rinishning tabiiy o'lchami. setContentHuggingPriority va setContentCompressionResistancePriority cho'zilish va siqilish paytida xatti-harakatni boshqaradi. sizeThatFits Auto Layoutda o'lchamni hisoblash uchun tizim tomonidan chaqiriladi. Maxsus ko'rinishlar uchun, komponentingiz tabiiy o'lchamga ega bo'lsa intrinsicContentSize ni bekor qiling — masalan, doira har doim 100x100 bo'lishi kerak.
onMeasure widthMeasureSpec va heightMeasureSpec ni qabul qiladi. MeasureSpec rejim va o'lchamni o'z ichiga oladi: UNSPECIFIED (cheklovlarsiz, Ko'rinish o'z o'lchamini tanlaydi), EXACTLY (ota-onadan aniq o'lcham), AT_MOST (maksimal o'lcham). setMeasuredDimension(width, height) o'lchash natijasini saqlaydi. Ma'lumotlar o'zgarganda, qayta o'lchash uchun requestLayout() ni chaqiring. Ichma-ich ViewGroup lar bolalar elementlarini joylashtirish uchun onLayout ni bekor qilishni talab qiladi.
| Platforma | O'lchash usuli | O'zgarishda chaqiruv | Qaytarish |
|---|---|---|---|
| iOS | sizeThatFits / intrinsicContentSize | setNeedsLayout / invalidateIntrinsicContentSize | CGSize |
| Android | onMeasure / setMeasuredDimension | requestLayout / invalidate | void (o'lchamni saqlaydi) |
| Flutter | computeDryLayout | setState / LayoutBuilder | Size |
computeDryLayout to'liq layout siklusiz o'lchamni hisoblash uchun RenderObject usulidir. LayoutBuilder.getSize — build usulida mavjud joyni olish uchun muqobil. Flutterda, kanvas o'lchami paint ga Size sifatida uzatiladi va alohida o'lchashni talab qilmaydi — CustomPainter uzatilgan chegaralar ichida chizadi. Biroq, maxsus RenderObject lar uchun performLayout va computeDryLayout ni bekor qilish kerak.
Tez-tez beriladigan savollar
drawRect Core Graphics orqali maxsus chizish uchun UIView usulidir. U Ko'rinishning birinchi renderida va har bir setNeedsDisplay() chaqiruvidan keyin chaqiriladi. Chiziqlar, shakllar va matn uchun drawRect ichida CGContext dan foydalaning.
View ni kengaytiruvchi sinf yarating, onDraw(Canvas canvas) ni bekor qiling va Canvas API dan foydalaning: drawCircle, drawRect, drawPath. Paint rang, qalinlik va uslubni sozlaydi. Yangilash uchun invalidate() ni chaqiring.
CustomPainter Canvasda maxsus chizish uchun Flutter sinfidir. paint(Canvas, Size) va shouldRepaint usullarini amalga oshiring. U CustomPaint vidjeti orqali joylashtiriladi. Flutterda drawRect yo'q — barcha chizish CustomPainter orqali amalga oshiriladi.
iOSda sizeThatFits va intrinsicContentSize dan foydalaning. Androidda — MeasureSpec bilan onMeasure. Flutterda, o'lcham paint(Canvas, Size) ga uzatiladi yoki computeDryLayout orqali hisoblanadi. Har bir platforma o'zining o'lchash usulidan foydalanadi.
Maxsus ko'rinishlar standart UIKit yoki View bilan amalga oshirib bo'lmaydigan noyob grafika, animatsiyalar, chartlar va elementlar uchun zarur. Oddiy uslublar uchun, standart komponentlarni sozlash kifoya — arxitekturani keraksiz murakkablashtirmang.
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.