Прилагођени прикази и цртање у мобилном развоју: суштина, који API и како ради

Аутор: IT Sectr Објављено: 2026-08-01 Време читања: 11 мин

Прилагођени прикази су основа јединственог интерфејса сваке мобилне апликације. Прилагођени прикази у мобилним апликацијама омогућавају креирање сопствене графике, анимација и елемената недоступних у стандардним компонентама. Према Apple Developer, 2025, drawRect остаје основни метод прилагођеног цртања у мобилном развоју на iOS-у. На Android-у исту улогу има onDraw са Canvas-ом, а у Flutter-у — CustomPainter.

Главно

  • Прилагођени прикази — кориснички дефинисане компоненте са сопственом логиком цртања, величине и понашања у мобилним апликацијама.
  • drawRect — метод UIView на iOS-у за прилагођено цртање кроз Core Graphics и CGContext.
  • onDraw — метод View на Android-у за цртање кроз Canvas и Paint са системом мерења onMeasure.
  • CustomPainter — класа Flutter-а за цртање на Canvas-у са методима paint и shouldRepaint.
  • Мерење — процес одређивања димензија Приказа кроз sizeThatFits на iOS-у, onMeasure на Android-у и computeDryLayout у Flutter-у.

Шта су прилагођени прикази и зашто су потребни у мобилним апликацијама

Прилагођени прикази су кориснички дефинисане интерфејс компоненте које преписују стандардне методе цртања и мерења за креирање јединствене графике. Графикони, анимације, дијаграми, прилагођени елементи ћаскања и AR маске — типични сценарији примене прилагођених приказа у мобилним апликацијама. Стандардне UI компоненте (Button, TextView, Label) покривају 80% задатака, али преосталих 20% захтева потпуну контролу над цртањем у мобилном развоју. Цртање у мобилном развоју је вештина која разликује junior програмера од senior-а.

Када су прилагођени прикази оправдани

Прилагођени прикази у мобилним апликацијама су потребни за јединствену 2D графику, сложене анимације, графиконе и визуелизацију података. Ако стандардни UIKit не пружа потребан елемент — креира се прилагођени приказ. У мобилним апликацијама, прилагођени прикази се користе за траке напретка, прилагођена дугмад, градијентна пуњења, анимиране иконе и платна за цртање прстом. Важно је не злоупотребљавати — за једноставне стилове довољно је подесити стандардне компоненте кроз Appearance API.

Прилагођени прикази на iOS-у: drawRect и Core Graphics

На iOS-у, прилагођени прикази се креирају наслеђивањем UIView-а и преписивањем метода drawRect. drawRect се позива при првом рендеровању и након сваког позива setNeedsDisplay(). Унутар drawRect-а, програмер добија CGContext кроз UIGraphicsGetCurrentContext() — платно за линије, облике, градијенте и текст. Core Graphics (Quartz 2D) је нисконivoнски CPU-базирани погон за рендеровање који даје потпуну контролу над сваким пикселом. UIBezierPath је згодан омотач за креирање путања са сажетом синтаксом.

swift
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: CGContext, CGGradient и трансформације

Core Graphics пружа CGContext — платно за све операције цртања. CGGradient креира линеарне и радијалне градијенте са подршком за CGColorSpace (sRGB, Display P3). Трансформације се изводе кроз CGAffineTransform — матрица 3x3 за ротацију, скалирање и померање. CGContextTranslateCTM, CGContextRotateCTM и CGContextScaleCTM мењају координатни систем. Core Graphics ради на CPU-у, па сложена графика може оптеретити процесор — за GPU убрзање користите Metal.

UIBezierPath за креирање облика

UIBezierPath је објектно-оријентисани омотач над CGPath-ом. Метод addArc(withCenter:radius:startAngle:endAngle:clockwise:) креира лукове и кругове, addCurve креира Безијерове криве. Путање подржавају операције спајања, пресека и одузимања кроз addClip. UIBezierPath је згодан за прилагођене маске (maskView), путање за сечење и сложене облике — звезде, срца, прилагођене иконе.

Прилагођени прикази на Android-у: onDraw и Canvas

На Android-у, прилагођени приказ проширује View са преписаном методом onDraw(Canvas). Canvas садржи све методе цртања у мобилном развоју: drawCircle, drawRect, drawLine, drawText, drawBitmap, drawPath и drawRoundRect. Paint подешава параметре — боју, дебљину линије, стил (FILL, STROKE, FILL_AND_STROKE), изглађивање (isAntiAlias) и величину текста. onDraw се позива сваки пут при invalidate() и не сме да садржи тешке операције — сва израчунавања се кеширају.

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

Path и анимације на Android-у

Path на Android-у је еквивалент UIBezierPath-а: addCircle, addRect, addOval, lineTo, cubicTo и quadTo. PathMeasure израчунава дужину путање и координате у било којој тачки — корисно за анимирање кретања објекта дуж путање. За анимације се користи ValueAnimator са invalidate() у повратном позиву. Аниматор може мењати боју, радијус, положај — било које својство које утиче на цртање. Прилагођени прикази на Android-у такође подржавају StateListDrawable и animated-vector за анимацију кроз XML.

Shader и градијенти у Canvas-у

Градијенти на Android-у се постављају кроз Shader — LinearGradient, RadialGradient и SweepGradient. Shader се додељује Paint-у кроз paint.setShader(shader). LinearGradient генерише линеарни градијент између две тачке са опционим позицијама боја. RadialGradient — радијални од центра ка ивицама. SweepGradient — конусни око централне тачке. Shader.TileMode (CLAMP, REPEAT, MIRROR) одређује понашање изван граница области.

CustomPainter у Flutter-у: цртање на Canvas-у

Flutter користи CustomPainter — класу са методима paint(Canvas canvas, Size size) и shouldRepaint. Canvas у Flutter-у пружа исте методе као у Android-у: drawCircle, drawRect, drawLine, drawPath, drawParagraph и drawImage. Paint у Flutter-у подешава боју, дебљину, стил и изглађивање. Flutter не користи drawRect ни onDraw — све цртање иде кроз CustomPainter, уграђен у CustomPaint виџет.

dart
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 и RepaintBoundary

shouldRepaint одређује да ли CustomPainter треба поново да црта. Вратите true само када се промене подаци који утичу на рендеровање — боја, величина, подаци графикона. RepaintBoundary изолује поновно цртање у засебан слој — користите за виџете који се ретко мењају. Flutter нема setNeedsDisplay или invalidate — поновно цртање се покреће кроз setState или ValueNotifier са ослушкивањем промена.

Градијенти и трансформације у Flutter-у

Flutter подржава LinearGradient, RadialGradient и SweepGradient — исте типове као у Android-у. Gradient креира Shader за Paint кроз createShader(Rect bounds). Трансформације се изводе кроз canvas.rotate, canvas.scale, canvas.translate и canvas.skew. Flutter користи матрицу трансформација 4x4 (Matrix4) за Transform виџет. Анимације цртања у Flutter-у се праве кроз AnimationController у спрези са setState-ом за поновно цртање CustomPainter-а.

Мерење прилагођених приказа: методи sizeThatFits, onMeasure и computeDryLayout

Коректно мерење прилагођених приказа је основа предвидљивог понашања интерфејса. На iOS-у, величина Приказа се одређује кроз sizeThatFits и intrinsicContentSize. sizeThatFits враћа оптималну величину за задата ограничења. intrinsicContentSize — природна величина садржаја без спољашњих ограничења. На Android-у, мерење се имплементира у onMeasure-у са параметрима MeasureSpec (UNSPECIFIED, EXACTLY, AT_MOST). У Flutter-у, величина се прослеђује paint(Canvas, Size) и може се израчунати кроз computeDryLayout или LayoutBuilder.

sizeThatFits и intrinsicContentSize на iOS-у

intrinsicContentSize враћа CGSize — природну величину Приказа на основу његовог садржаја. setContentHuggingPriority и setContentCompressionResistancePriority контролишу понашање при истезању и сабијању. sizeThatFits позива систем за израчунавање величине у Auto Layout-у. За прилагођене приказе, препишите intrinsicContentSize ако ваша компонента има природну величину — на пример, круг увек треба да буде 100x100.

onMeasure и MeasureSpec на Android-у

onMeasure прихвата widthMeasureSpec и heightMeasureSpec. MeasureSpec садржи режим и величину: UNSPECIFIED (без ограничења, Приказ сам бира величину), EXACTLY (тачна величина од родитеља), AT_MOST (максимална величина). setMeasuredDimension(width, height) чува резултат мерења. При промени података, позовите requestLayout() за поновно мерење. Угнежђени ViewGroup захтевају преписивање onLayout-а за распоређивање дечијих елемената.

ПлатформаМетод мерењаПозив при промениПовратак
iOSsizeThatFits / intrinsicContentSizesetNeedsLayout / invalidateIntrinsicContentSizeCGSize
AndroidonMeasure / setMeasuredDimensionrequestLayout / invalidatevoid (чува величину)
FluttercomputeDryLayoutsetState / LayoutBuilderSize

computeDryLayout у Flutter-у

computeDryLayout је метод RenderObject-а за израчунавање величине без пуног циклуса распореда. LayoutBuilder.getSize — алтернатива за добијање доступног простора у build методу. У Flutter-у, величина платна се прослеђује paint-у као Size и не захтева засебно мерење — CustomPainter црта унутар прослеђених граница. Међутим, за прилагођене RenderObject-е, потребно је преписивати performLayout и computeDryLayout.

Често постављана питања

Шта је drawRect на iOS-у и када се позива?

drawRect је метод UIView-а за прилагођено цртање кроз Core Graphics. Позива се при првом рендеровању Приказа и након сваког позива setNeedsDisplay(). Користите CGContext унутар drawRect-а за линије, облике и текст.

Како цртати на Android-у помоћу Canvas-а?

Направите класу која проширује View, препишите onDraw(Canvas canvas) и користите Canvas API: drawCircle, drawRect, drawPath. Paint подешава боју, дебљину и стил. За ажурирање позовите invalidate().

Шта је CustomPainter у Flutter-у?

CustomPainter је класа Flutter-а за прилагођено цртање на Canvas-у. Имплементирајте методе paint(Canvas, Size) и shouldRepaint. Поставља се кроз CustomPaint виџет. Flutter нема drawRect — све цртање иде кроз CustomPainter.

Како измерити величину прилагођеног приказа?

На iOS-у користите sizeThatFits и intrinsicContentSize. На Android-у — onMeasure са MeasureSpec. У Flutter-у, величина се прослеђује paint(Canvas, Size) или израчунава кроз computeDryLayout. Свака платформа користи сопствени метод мерења.

Када користити прилагођене приказе уместо стандардних компоненти?

Прилагођени прикази су потребни за јединствену графику, анимације, графиконе и елементе који се не могу имплементирати стандардним UIKit-ом или View-ом. За једноставне стилове, довољно је подесити стандардне компоненте — не компликујте архитектуру без потребе.

Резиме

  • Прилагођени прикази — основа јединствених интерфејса за графиконе, анимације и нестандардне елементе у мобилним апликацијама.
  • drawRect — метод iOS-а за цртање кроз Core Graphics са CGContext и UIBezierPath.
  • onDraw — метод Android-а за цртање кроз Canvas и Paint са подршком за Path и Shader.
  • CustomPainter — класа Flutter-а за цртање на Canvas-у са shouldRepaint и RepaintBoundary.
  • Мерење — валидација величина кроз sizeThatFits (iOS), onMeasure (Android) и computeDryLayout (Flutter).
  • Цртање у мобилном развоју на свим платформама следи јединствени образац: добити контекст, подесити стилове и нацртати примитиве.
  • Кеширајте објекте цртања (Paint, Path) — не креирајте их унутар drawRect, onDraw или paint за стабилне перформансе.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту