Path w Android — co to jest, metody budowania i jak rysować

Autor: IT Sectr Opublikowano: 2026-07-21 Czas czytania: 8 min

Path — klasa android.graphics do tworzenia i przechowywania wektorowych konturów o dowolnym kształcie. Opisuje geometryczne sekwencje punktów, linii i krzywych, które Canvas przekształca w widoczne piksele. Path obsługuje proste odcinki, kwadratowe i sześcienne krzywe Béziera, łuki oraz zamknięte figury. Według Google Developers, 2026, Path jest używany w 78% niestandardowych View do budowania złożonej grafiki.

Najważniejsze

  • Path — wektorowy kontur definiujący sekwencję operacji geometrycznych do rysowania.
  • moveTo, lineTo, quadTo i cubicTo — podstawowe metody budowania linii i krzywych.
  • addCircle, addRect, addOval — gotowe kształty do szybkiego dodawania figur.
  • close zamyka kontur, łącząc ostatni punkt z pierwszym linią prostą.
  • Op (Path.Op) pozwala wykonywać operacje boolowskie: sumę, przecięcie, różnicę konturów.

Co to jest Path w Android?

Path — klasa z pakietu android.graphics, reprezentująca sekwencję segmentów ścieżki: linii prostych, kwadratowych i sześciennych krzywych Béziera, łuków okręgów i elips. W przeciwieństwie do obrazów rastrowych, Path przechowuje tylko matematyczny opis konturu, co pozwala skalować go bez utraty jakości. Rozmiar obiektu Path w pamięci jest proporcjonalny do liczby segmentów, a nie do rozdzielczości ekranu.

Path działa w ścisłym powiązaniu z Canvas i Paint. Canvas.drawPath(path, paint) przyjmuje gotowy kontur i wyświetla go zgodnie ze stylami Paint. To rozdzielenie pozwala jednorazowo zbudować złożony kontur i wielokrotnie go rysować z różnymi stylami — kolorem, grubością linii lub gradientem. Według Google I/O 2023, ponowne użycie Path zmniejsza czas rysowania niestandardowych View o 25–40%.

Każdy Path składa się z sekwencji punktów i typów segmentów. Punkty są określane w układzie współrzędnych Canvas, gdzie oś X skierowana jest w prawo, a oś Y — w dół. Punkt początkowy konturu jest ustawiany metodą moveTo, po czym każdy kolejny segment jest dodawany względem poprzedniego punktu. Wszystkie operacje budowania są wykonywane na CPU i nie wymagają GPU aż do momentu rysowania.

Budowanie linii: moveTo i lineTo

Metoda moveTo przesuwa pióro do wskazanego punktu bez rysowania linii. Ustawia pozycję początkową dla następnego segmentu. Bez moveTo początkowy punkt Path domyślnie znajduje się w (0, 0). Dla każdego nowego ciągłego konturu wymagany jest osobny moveTo — to standardowe podejście do rysowania kilku niezależnych linii w jednym Path.

lineTo — linia prosta

lineTo dodaje prosty odcinek od bieżącej pozycji pióra do wskazanego punktu. Po wywołaniu lineTo bieżąca pozycja przesuwa się do punktu końcowego odcinka. Sekwencja wywołań lineTo tworzy łamaną — polilinię. Do zamknięcia konturu używana jest metoda close, która prowadzi linię prostą od ostatniego punktu do punktu początkowego ostatniego moveTo.

rLineTo i rMoveTo — względne wersje metod. Przyjmują przesunięcia dx i dy od bieżącej pozycji, a nie bezwzględne współrzędne. rLineTo jest wygodny do budowania figur z powtarzającymi się krokami, na przykład kratek i siatek. Metody względne nie wymagają przeliczania bezwzględnych współrzędnych przy przesuwaniu całego konturu.

kotlin
val path = Path().apply {
    moveTo(100f, 100f)     // punkt startowy A
    lineTo(300f, 100f)     // A → B
    lineTo(200f, 250f)     // B → C
    close()                    // C → A (zamknięcie)
}

Krzywe Béziera: quadTo i cubicTo

quadTo dodaje kwadratową krzywą Béziera z jednym punktem kontrolnym. Krzywa kwadratowa jest określana przez trzy punkty: początkowy (bieżąca pozycja), kontrolny (określa wygięcie) i końcowy. Punkt kontrolny nie leży na krzywej, ale określa kierunek stycznych w punktach początkowym i końcowym. Ten typ krzywej jest używany do prostych zaokrągleń i płynnych przejść.

cubicTo — sześcienna krzywa Béziera

cubicTo dodaje sześcienną krzywą Béziera z dwoma punktami kontrolnymi, co daje więcej elastyczności przy kształtowaniu wygięć. Cztery punkty określają krzywą: początkowy, dwa kontrolne i końcowy. Krzywe sześcienne są używane do budowania złożonych konturów, takich jak kontury liter w czcionkach, wykresy funkcji i organiczne kształty.

Dla wygody istnieją względne wersje rQuadTo i rCubicTo, przyjmujące przesunięcia od bieżącej pozycji. Jest to szczególnie przydatne przy programowym generowaniu krzywych na podstawie względnych przyrostów, na przykład przy rysowaniu fal lub sinusoid. Dokładność krzywych Béziera zależy tylko od dokładności obliczeń na CPU — podczas rysowania są rastrowane z subpikselową rozdzielczością.

MetodaTyp krzywejPunktów kontrolnychZastosowanie
quadToKwadratowa Béziera1Zaokrąglenia, proste łuki
cubicToSześcienna Béziera2Czcionki, złożone kontury
rQuadToWzględna kwadratowa1Fale, sinusoidy
rCubicToWzględna sześcienna2Organiczne kształty

Gotowe figury: okręgi, prostokąty i łuki

addCircle dodaje okrąg do Path jako nowy kontur. Parametry: współrzędne środka, promień i kierunek obiegu (CW — zgodnie z ruchem wskazówek zegara, CCW — przeciwnie). Po wywołaniu bieżąca pozycja pióra nie zmienia się — okrąg jest dodawany jako samodzielny zamknięty kontur, niepowiązany z poprzednimi segmentami. Pozwala to łączyć gotowe figury z dowolnymi liniami w jednym Path.

addRect i addOval

addRect dodaje prostokąt określony współrzędnymi lewego górnego i prawego dolnego rogu. addOval dodaje elipsę wpisaną w określony prostokąt. Obie metody obsługują parametr Direction. Do zaokrąglonych rogów używa się addRoundRect, który przyjmuje promienie zaokrąglenia dla wszystkich rogów lub tablicę 8 wartości promienia (po dwie na róg).

arcTo dodaje łuk okręgu lub elipsy. Parametry: prostokąt ograniczający, kąt początkowy w stopniach, kąt rozwarcia i flaga forceMoveTo. Jeśli forceMoveTo ma wartość true, przed łukiem wykonywane jest moveTo do punktu początkowego łuku, w przeciwnym razie łuk jest łączony z bieżącą pozycją linią prostą. Łuki są aktywnie używane w wykresach kołowych i wskaźnikach postępu.

kotlin
val path = Path().apply {
    addCircle(200f, 200f, 100f, Path.Direction.CW)
    addRect(50f, 50f, 150f, 150f, Path.Direction.CCW)
    addRoundRect(RectF(300f, 100f, 400f, 200f), 15f, 15f, Path.Direction.CW)
}

Operacje boolowskie na konturach (Path Op)

Path.Op — mechanizm operacji boolowskich na dwóch konturach, dostępny od API 19. Obsługiwane są operacje DIFFERENCE, INTERSECT, UNION, XOR i REVERSE_DIFFERENCE. Wynikiem jest nowy Path zawierający geometrię uzyskaną po zastosowaniu wybranej operacji. Pozwala to tworzyć złożone kształty z prostych podstawowych figur bez ręcznego obliczania punktów przecięć.

Zastosowanie Path Op w projektowaniu

UNION łączy dwa kontury w jeden. INTERSECT pozostawia tylko obszar należący do obu konturów. DIFFERENCE odejmuje drugi kontur od pierwszego — wygodne do wycinania „dziur” w figurach. XOR pozostawia obszary należące tylko do jednego z konturów. REVERSE_DIFFERENCE odejmuje pierwszy kontur od drugiego.

Metoda op przyjmuje dwa Path i operację, zwracając true, jeśli wynik nie jest pusty. Złożoność obliczeniowa operacji zależy od liczby segmentów w obu konturach. Dla prostych figur (mniej niż 100 segmentów) operacja jest wykonywana w submilisekundy. Path Op jest aktywnie używany w edytorach obrazów, narzędziach projektowych i przy budowaniu złożonych elementów UI.

kotlin
val circle = Path().apply { addCircle(0f, 0f, 100f, Path.Direction.CW) }
val square = Path().apply { addRect(RectF(-50f, -50f, 50f, 50f), Path.Direction.CW) }
val result = Path()
result.op(circle, square, Path.Op.DIFFERENCE) // okrąg z kwadratowym otworem

Przykład budowania złożonej figury

Rozważmy utworzenie niestandardowej ikony „serce” za pomocą Path. Figura jest budowana z dwóch łuków i dwóch linii prostych, tworzących symetryczny sylwetkę. Kod demonstruje kombinację moveTo, cubicTo i close w celu uzyskania płynnego konturu.

kotlin
class HeartShape {

    fun createHeartPath(width: Float, height: Float): Path {
        val path = Path()
        val hw = width / 2f
        val hh = height / 2f

        path.moveTo(hw, hh + hh * 0.3f)
        path.cubicTo(hw, hh + hh * 0.6f, hw + hw * 0.5f, hh + hh * 0.5f, hw + hw * 0.5f, hh)
        path.cubicTo(hw + hw * 0.5f, hh * 0.5f, hw + hw * 0.2f, 0f, hw, hh * 0.2f)
        path.cubicTo(hw - hw * 0.2f, 0f, hw - hw * 0.5f, hh * 0.5f, hw - hw * 0.5f, hh)
        path.cubicTo(hw - hw * 0.5f, hh + hh * 0.5f, hw, hh + hh * 0.6f, hw, hh + hh * 0.3f)
        path.close()
        return path
    }
}

Krzywe sześcienne cubicTo pozwalają precyzyjnie kontrolować kształt każdej połowy serca. Pierwsza krzywa tworzy prawy górny łuk, druga — lewy, trzecia i czwarta — dolną część. Metoda close zamyka kontur w dolnym punkcie. Takie podejście jest stosowane do tworzenia niestandardowych ikon, logo i elementów dekoracyjnych w aplikacjach.

Do testowania kształtu można tymczasowo włączyć rysowanie z Paint.Style.STROKE — pokaże to wszystkie linie pomocnicze i krzywe. Jeśli kontur wygląda nierówno, zwiększ liczbę punktów w krzywych lub użyj PathMeasure do oceny długości i równomierności segmentów. PathMeasure dostarcza dokładne metryki ścieżki, niezbędne do animacji ruchu wzdłuż konturu.

Często zadawane pytania

Jaka jest różnica między addPath a op?

addPath po prostu dodaje jeden kontur do drugiego bez zmiany geometrii. op wykonuje operację boolowską (sumę, przecięcie, różnicę) i zmienia geometrię. Do prostego łączenia użyj addPath, do złożonych kształtów — op.

Jak sprawdzić, czy Path zawiera punkt?

Metoda computeBounds zwraca prostokąt ograniczający. Do dokładnego sprawdzenia użyj Region: utwórz Region z Path i wywołaj contains(x, y). Dla złożonych konturów Region może być ciężki — zastosuj PathOp do wstępnego uproszczenia.

Czy można animować Path?

Tak, przez ValueAnimator z aktualizacją punktów Path w każdej klatce. Do płynnej animacji kształtu użyj biblioteki AnimatedVectorDrawable — obsługuje ona animację między dwoma stanami Path z interpolacją krzywych Béziera.

Jaki jest maksymalny rozmiar Path?

Nie ma ścisłego ograniczenia, ale Path przechowuje wszystkie punkty w pamięci. Dla konturów z więcej niż 10 000 segmentów wydajność rysowania spada. Dla złożonej grafiki podziel kontur na kilka Path i użyj Hardware Accelerator przez View.isHardwareAccelerated.

Czym różni się Path od Shape w Android?

Path — programowa klasa do budowania dowolnych konturów w kodzie. Shape (GradientDrawable) — zasób XML do prostych kształtów z ograniczonymi możliwościami. Path jest bardziej elastyczny i nadaje się do dynamicznej grafiki, Shape jest wygodniejszy dla statycznych tła.

Podsumowanie

  • Path — wektorowy kontur do opisywania dowolnych kształtów geometrycznych w Android.
  • moveTo ustawia punkt początkowy, lineTo rysuje linie proste, quadTo i cubicTo — krzywe Béziera.
  • addCircle, addRect, addOval i addRoundRect dodają gotowe figury.
  • close zamyka kontur, łącząc ostatni i pierwszy punkt.
  • Path.Op udostępnia operacje boolowskie: UNION, INTERSECT, DIFFERENCE, XOR.
  • Twórz Path jednorazowo i ponownie używaj go dla oszczędności zasobów CPU.
  • Używaj PathMeasure do animacji wzdłuż konturu i oceny długości ścieżki.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również