Vlastní zobrazení a kreslení v mobilním vývoji: podstata, jaká API a jak to funguje

Autor: IT Sectr Publikováno: 2026-08-01 Doba čtení: 11 min

Vlastní zobrazení jsou základem jedinečného rozhraní každé mobilní aplikace. Vlastní zobrazení v mobilních aplikacích umožňují vytvářet vlastní grafiku, animace a prvky nedostupné ve standardních komponentách. Podle Apple Developer, 2025 zůstává drawRect hlavní metodou vlastního kreslení v mobilním vývoji na iOS. Na Androidu hraje stejnou roli onDraw s Canvasem a ve Flutter — CustomPainter.

Hlavní body

  • Vlastní zobrazení — uživatelsky definované komponenty s vlastní logikou kreslení, velikosti a chování v mobilních aplikacích.
  • drawRect — metoda UIView na iOS pro vlastní kreslení přes Core Graphics a CGContext.
  • onDraw — metoda View na Androidu pro kreslení přes Canvas a Paint s měřicím systémem onMeasure.
  • CustomPainter — třída Flutter pro kreslení na Canvas s metodami paint a shouldRepaint.
  • Měření — proces určování rozměrů Zobrazení přes sizeThatFits na iOS, onMeasure na Androidu a computeDryLayout ve Flutter.

Co jsou vlastní zobrazení a proč jsou potřebná v mobilních aplikacích

Vlastní zobrazení jsou uživatelsky definované komponenty rozhraní, které přepisují standardní metody kreslení a měření pro vytváření jedinečné grafiky. Grafy, animace, diagramy, vlastní prvky chatu a AR masky — to jsou typické scénáře použití vlastních zobrazení v mobilních aplikacích. Standardní UI komponenty (Button, TextView, Label) pokrývají 80% úkolů, ale zbývajících 20% vyžaduje úplnou kontrolu nad kreslením v mobilním vývoji. Kreslení v mobilním vývoji je dovednost, která odlišuje junior vývojáře od seniora.

Kdy jsou vlastní zobrazení oprávněná

Vlastní zobrazení v mobilních aplikacích jsou potřebná pro jedinečnou 2D grafiku, složité animace, grafy a vizualizaci dat. Pokud standardní UIKit neposkytuje požadovaný prvek — vytvoří se vlastní zobrazení. V mobilních aplikacích se vlastní zobrazení používají pro ukazatele průběhu, vlastní tlačítka, přechodové výplně, animované ikony a plátna pro kreslení prstem. Je důležité to nepřehánět — pro jednoduché styly stačí nakonfigurovat standardní komponenty přes API vzhledu.

Vlastní zobrazení na iOS: drawRect a Core Graphics

Na iOS se vlastní zobrazení vytvářejí děděním z UIView a přepsáním metody drawRect. drawRect se volá při prvním vykreslení a po každém volání setNeedsDisplay(). Uvnitř drawRect získá vývojář CGContext přes UIGraphicsGetCurrentContext() — plátno pro čáry, tvary, přechody a text. Core Graphics (Quartz 2D) je nízkoúrovňový vykreslovací engine na CPU, který poskytuje úplnou kontrolu nad každým pixelem. UIBezierPath je pohodlný obal pro vytváření cest se stručnou syntaxí.

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 a transformace

Core Graphics poskytuje CGContext — plátno pro všechny kreslicí operace. CGGradient vytváří lineární a radiální přechody s podporou CGColorSpace (sRGB, Display P3). Transformace se provádějí přes CGAffineTransform — matice 3x3 pro otáčení, škálování a posun. CGContextTranslateCTM, CGContextRotateCTM a CGContextScaleCTM mění souřadnicový systém. Core Graphics běží na CPU, takže složitá grafika může zatěžovat procesor — pro GPU akceleraci použijte Metal.

UIBezierPath pro vytváření tvarů

UIBezierPath je objektově orientovaný obal nad CGPath. Metoda addArc(withCenter:radius:startAngle:endAngle:clockwise:) vytváří oblouky a kruhy, addCurve vytváří Bézierovy křivky. Cesty podporují operace sjednocení, průniku a odečítání přes addClip. UIBezierPath je vhodný pro vlastní masky (maskView), ořezové cesty a složité tvary — hvězdy, srdce, vlastní ikony.

Vlastní zobrazení na Androidu: onDraw a Canvas

Na Androidu vlastní zobrazení rozšiřuje View s přepsaným onDraw(Canvas). Canvas obsahuje všechny metody kreslení v mobilním vývoji: drawCircle, drawRect, drawLine, drawText, drawBitmap, drawPath a drawRoundRect. Paint konfiguruje parametry — barvu, tloušťku čáry, styl (FILL, STROKE, FILL_AND_STROKE), vyhlazování (isAntiAlias) a velikost textu. onDraw se volá při každém invalidate() a neměl by obsahovat těžké operace — všechny výpočty se ukládají do mezipaměti.

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 a animace na Androidu

Path na Androidu je ekvivalentem UIBezierPath: addCircle, addRect, addOval, lineTo, cubicTo a quadTo. PathMeasure vypočítává délku cesty a souřadnice v libovolném bodě — užitečné pro animaci pohybu objektu podél cesty. Pro animace se používá ValueAnimator s invalidate() ve zpětném volání. Animátor může měnit barvu, poloměr, pozici — jakoukoli vlastnost ovlivňující kreslení. Vlastní zobrazení na Androidu také podporují StateListDrawable a animated-vector pro animace přes XML.

Shader a přechody v Canvas

Přechody na Androidu se nastavují přes Shader — LinearGradient, RadialGradient a SweepGradient. Shader se přiřazuje k Paint přes paint.setShader(shader). LinearGradient generuje lineární přechod mezi dvěma body s volitelnými pozicemi barev. RadialGradient — radiální od středu k okrajům. SweepGradient — kuželový kolem středového bodu. Shader.TileMode (CLAMP, REPEAT, MIRROR) určuje chování za hranicemi oblasti.

CustomPainter ve Flutter: kreslení na Canvas

Flutter používá CustomPainter — třídu s metodami paint(Canvas canvas, Size size) a shouldRepaint. Canvas ve Flutter poskytuje stejné metody jako v Androidu: drawCircle, drawRect, drawLine, drawPath, drawParagraph a drawImage. Paint ve Flutter konfiguruje barvu, tloušťku, styl a vyhlazování. Flutter nepoužívá drawRect ani onDraw — veškeré kreslení probíhá přes CustomPainter, vložený do widgetu 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 a RepaintBoundary

shouldRepaint určuje, zda je třeba CustomPainter překreslit. Vracejte true pouze při změně dat ovlivňujících vykreslování — barva, velikost, data grafu. RepaintBoundary izoluje překreslování do samostatné vrstvy — používejte pro widgety, které se mění zřídka. Flutter nemá setNeedsDisplay ani invalidate — překreslování se spouští přes setState nebo ValueNotifier s nasloucháním změn.

Přechody a transformace ve Flutter

Flutter podporuje LinearGradient, RadialGradient a SweepGradient — stejné typy jako v Androidu. Gradient vytváří Shader pro Paint přes createShader(Rect bounds). Transformace se provádějí přes canvas.rotate, canvas.scale, canvas.translate a canvas.skew. Flutter používá transformační matici 4x4 (Matrix4) pro widget Transform. Animace kreslení ve Flutter se vytvářejí pomocí AnimationController v kombinaci se setState pro překreslení CustomPainter.

Měření vlastních zobrazení: metody sizeThatFits, onMeasure a computeDryLayout

Správné měření vlastních zobrazení je základem předvídatelného chování rozhraní. Na iOS se velikost Zobrazení určuje přes sizeThatFits a intrinsicContentSize. sizeThatFits vrací optimální velikost pro daná omezení. intrinsicContentSize — přirozená velikost obsahu bez vnějších omezení. Na Androidu je měření implementováno v onMeasure s parametry MeasureSpec (UNSPECIFIED, EXACTLY, AT_MOST). Ve Flutter se velikost předává do paint(Canvas, Size) a lze ji vypočítat přes computeDryLayout nebo LayoutBuilder.

sizeThatFits a intrinsicContentSize na iOS

intrinsicContentSize vrací CGSize — přirozenou velikost Zobrazení na základě jeho obsahu. setContentHuggingPriority a setContentCompressionResistancePriority řídí chování při natahování a stlačování. sizeThatFits volá systém pro výpočet velikosti v Auto Layout. Pro vlastní zobrazení přepište intrinsicContentSize, pokud má váš komponent přirozenou velikost — například kruh by měl být vždy 100x100.

onMeasure a MeasureSpec na Androidu

onMeasure přijímá widthMeasureSpec a heightMeasureSpec. MeasureSpec obsahuje režim a velikost: UNSPECIFIED (bez omezení, Zobrazení si volí vlastní velikost), EXACTLY (přesná velikost od rodiče), AT_MOST (maximální velikost). setMeasuredDimension(width, height) ukládá výsledek měření. Při změně dat zavolejte requestLayout() pro přeměření. Vnořené ViewGroup vyžadují přepsání onLayout pro uspořádání podřízených prvků.

PlatformaMetoda měřeníVolání při změněNávrat
iOSsizeThatFits / intrinsicContentSizesetNeedsLayout / invalidateIntrinsicContentSizeCGSize
AndroidonMeasure / setMeasuredDimensionrequestLayout / invalidatevoid (ukládá velikost)
FluttercomputeDryLayoutsetState / LayoutBuilderSize

computeDryLayout ve Flutter

computeDryLayout je metoda RenderObject pro výpočet velikosti bez úplného cyklu rozvržení. LayoutBuilder.getSize — alternativa pro získání dostupného prostoru v metodě build. Ve Flutter se velikost plátna předává do paint jako Size a nevyžaduje samostatné měření — CustomPainter kreslí v předaných hranicích. Pro vlastní RenderObject je však třeba přepsat performLayout a computeDryLayout.

Často kladené otázky

Co je drawRect na iOS a kdy se volá?

drawRect je metoda UIView pro vlastní kreslení přes Core Graphics. Volá se při prvním vykreslení Zobrazení a po každém volání setNeedsDisplay(). Použijte CGContext uvnitř drawRect pro čáry, tvary a text.

Jak kreslit na Androidu pomocí Canvas?

Vytvořte třídu rozšiřující View, přepište onDraw(Canvas canvas) a použijte Canvas API: drawCircle, drawRect, drawPath. Paint konfiguruje barvu, tloušťku a styl. Pro aktualizaci zavolejte invalidate().

Co je CustomPainter ve Flutter?

CustomPainter je třída Flutter pro vlastní kreslení na Canvas. Implementujte metody paint(Canvas, Size) a shouldRepaint. Umísťuje se přes widget CustomPaint. Flutter nemá drawRect — veškeré kreslení probíhá přes CustomPainter.

Jak změřit velikost vlastního zobrazení?

Na iOS použijte sizeThatFits a intrinsicContentSize. Na Androidu — onMeasure s MeasureSpec. Ve Flutter se velikost předává do paint(Canvas, Size) nebo se vypočítá přes computeDryLayout. Každá platforma používá vlastní metodu měření.

Kdy použít vlastní zobrazení místo standardních komponent?

Vlastní zobrazení jsou potřebná pro jedinečnou grafiku, animace, grafy a prvky, které nelze implementovat standardním UIKit nebo View. Pro jednoduché styly stačí nakonfigurovat standardní komponenty — nekomplikujte architekturu zbytečně.

Shrnutí

  • Vlastní zobrazení — základ jedinečných rozhraní pro grafy, animace a nestandardní prvky v mobilních aplikacích.
  • drawRect — metoda iOS pro kreslení přes Core Graphics s CGContext a UIBezierPath.
  • onDraw — metoda Androidu pro kreslení přes Canvas a Paint s podporou Path a Shader.
  • CustomPainter — třída Flutter pro kreslení na Canvas s shouldRepaint a RepaintBoundary.
  • Měření — validace velikostí přes sizeThatFits (iOS), onMeasure (Android) a computeDryLayout (Flutter).
  • Kreslení v mobilním vývoji na všech platformách následuje jednotný vzor: získat kontext, nakonfigurovat styly a nakreslit primitiva.
  • Ukládejte do mezipaměti kreslicí objekty (Paint, Path) — nevytvářejte je uvnitř drawRect, onDraw nebo paint pro stabilní výkon.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt