Wiele aplikacji musi mieć możliwość precyzyjnego kontrolowania tego, co jest wyświetlane na ekranie. Może to być na przykład umieszczenie pudełka lub okręgu na ekranie w odpowiednim miejscu. Może to też być skomplikowana grafika w różnych stylach.
Podstawowy rysunek z modyfikatorami i DrawScope
Głównym sposobem tworzenia elementów niestandardowych w sekcji Komponowanie jest używanie modyfikatorów, takich jak Modifier.drawWithContent
, Modifier.drawBehind
i Modifier.drawWithCache
.
Aby na przykład narysować coś za kompozycją, możesz użyć modyfikatora drawBehind
, aby rozpocząć wykonywanie poleceń rysowania:
Spacer( modifier = Modifier .fillMaxSize() .drawBehind { // this = DrawScope } )
Jeśli potrzebujesz tylko kompozytowalnej funkcji, która rysuje, możesz użyć kompozytowalnej funkcji Canvas
. Komponent Canvas
to wygodna szata dla Modifier.drawBehind
. Umieść Canvas
w swoim układzie tak samo jak dowolny inny element interfejsu tworzenia wiadomości. W ciągu
Canvas
, możesz rysować elementy, zachowując ich dokładną kontrolę nad ich stylem
lokalizacji.
Wszystkie modyfikatory rysowania udostępniają DrawScope
– środowisko rysowania o zakresie
która zachowuje własny stan. Umożliwia to ustawienie parametrów dla grupy
elementów graficznych. Obiekt DrawScope
zawiera kilka przydatnych pól, takich jak size
,
oraz obiekt Size
określający bieżące wymiary obiektu DrawScope
.
Aby coś narysować, możesz użyć jednej z wielu funkcji rysowania w DrawScope
. Dla:
poniższy kod spowoduje narysowanie prostokąta w lewym górnym rogu
ekran:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F drawRect( color = Color.Magenta, size = canvasQuadrantSize ) }

Więcej informacji o różnych modyfikatorach rysowania znajdziesz w dokumentacji Modyfikatory grafiki.
Układ współrzędnych
Aby narysować coś na ekranie, musisz znać przesunięcie (x
i y
) oraz rozmiar
Twój produkt. W przypadku wielu metod rysowania w obiekcie DrawScope
pozycja i rozmiar są podawane przez domyślne wartości parametrów. Parametry domyślne zwykle umieszczają element w miejscu [0, 0]
na kanwie i zapewniają domyślną wartość size
, która wypełnia całą powierzchnię rysunku, jak w przykładzie powyżej – prostokąt jest umieszczony w lewym górnym rogu. Aby dostosować rozmiar i położenie elementu, musisz zrozumieć system współrzędnych w Compose.
Punkt początkowy układu współrzędnych ([0,0]
) znajduje się w lewym górnym rogu piksela
obszar rysowania. Wartość x
rośnie, gdy przesuwasz ją w prawo, a wartość y
– gdy przesuwasz ją w dół.
![Siatka z układem współrzędnych z lewym górnym [0, 0] i prawym dolnym [szerokość, wysokość]](https://developer.android.google.cn/static/develop/ui/compose/images/graphics/introduction/compose_coordinate_system_drawing.png?hl=pl)
Jeśli na przykład chcesz narysować ukośną linię od prawego górnego rogu
obszaru roboczego w lewym dolnym rogu, możesz użyć
DrawScope.drawLine()
i podaj przesunięcie czasu rozpoczęcia i zakończenia za pomocą funkcji
odpowiednie pozycje x i y:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasWidth = size.width val canvasHeight = size.height drawLine( start = Offset(x = canvasWidth, y = 0f), end = Offset(x = 0f, y = canvasHeight), color = Color.Blue ) }
Przekształcenia podstawowe
DrawScope
oferuje przekształcenia umożliwiające zmianę miejsca lub sposobu poleceń rysowania
.
Skala
Użyj parametru DrawScope.scale()
, aby zwiększyć rozmiar operacji rysowania. Operacje takie jak
scale()
ma zastosowanie do wszystkich operacji rysowania w ramach danej funkcji lambda. Dla:
przykład: ten kod zwiększa scaleX
10 razy i scaleY
15
razy:
Canvas(modifier = Modifier.fillMaxSize()) { scale(scaleX = 10f, scaleY = 15f) { drawCircle(Color.Blue, radius = 20.dp.toPx()) } }

Przetłumacz
Użyj
DrawScope.translate()
możesz przesuwać elementy rysowania w górę, w dół, w lewo lub w prawo. Na przykład kod poniżej przesuwa rysunek o 100 pikseli w prawo i o 300 pikseli w górę:
Canvas(modifier = Modifier.fillMaxSize()) { translate(left = 100f, top = -300f) { drawCircle(Color.Blue, radius = 200.dp.toPx()) } }

Obróć
Użyj opcji DrawScope.rotate()
, aby obracać rysunek wokół punktu obrotu. Na przykład parametr
ten kod obraca prostokąt o 45 stopni:
Canvas(modifier = Modifier.fillMaxSize()) { rotate(degrees = 45F) { drawRect( color = Color.Gray, topLeft = Offset(x = size.width / 3F, y = size.height / 3F), size = size / 3F ) } }

rotate()
, by zastosować obrót do bieżącego zakresu rysowania, który powoduje obrót prostokąta o 45 stopni.
Odcięcie
Użyj DrawScope.inset()
, aby dostosować domyślne parametry bieżącego
DrawScope
, zmienianie granic rysowania i tłumaczenie rysunków
odpowiednio:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F inset(horizontal = 50f, vertical = 30f) { drawRect(color = Color.Green, size = canvasQuadrantSize) } }
Ten kod dodaje wypełnienie do poleceń rysowania:

Wiele przekształceń
Aby zastosować wiele przekształceń do rysunków, użyj funkcji
funkcji DrawScope.withTransform()
, która tworzy i
pozwala zastosować jedno przekształcenie, które łączy wszystkie pożądane zmiany. Użycie funkcji withTransform()
jest wydajniejsze niż wywoływanie zagnieżdżonych funkcji w przypadku poszczególnych przekształceń, ponieważ wszystkie przekształcenia są wykonywane razem w ramach pojedynczej operacji, a nie wymagają obliczania i zapisywania przez funkcję Compose poszczególnych zagnieżdżonych przekształceń.
Na przykład ten kod stosuje zarówno translację, jak i obrót do prostokąt:
Canvas(modifier = Modifier.fillMaxSize()) { withTransform({ translate(left = size.width / 5F) rotate(degrees = 45F) }) { drawRect( color = Color.Gray, topLeft = Offset(x = size.width / 3F, y = size.height / 3F), size = size / 3F ) } }

withTransform
, aby zastosować zarówno obrót, jak i translację, obracając prostokąt i przesuwając go w lewo.Typowe operacje rysowania
Rysowanie tekstu
Do rysowania tekstu w funkcji tworzenia wiadomości zwykle możesz użyć funkcji kompozycyjnej Text
. Jeśli jednak korzystasz z poziomu DrawScope
lub chcesz ręcznie narysować tekst z użyciem funkcji dostosowywania, możesz użyć metody DrawScope.drawText()
.
Aby narysować tekst, utwórz obiekt TextMeasurer
za pomocą obiektu rememberTextMeasurer
i wywołaj funkcję drawText
z użyciem narzędzia do pomiaru:
val textMeasurer = rememberTextMeasurer() Canvas(modifier = Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello") }

Zmierz tekst
Rysowanie tekstu działa nieco inaczej niż inne polecenia rysowania. Zazwyczaj podajesz polecenie rysowania rozmiar (szerokość i wysokość), aby narysować kształt lub obraz. W przypadku tekstu rozmiar renderowanej reklamy zależy od kilku parametrów. takich jak rozmiar i czcionka, ligatury czy odstępy między literami.
Aby uzyskać dostęp do zmierzonych wyników, możesz użyć opcji TextMeasurer
wielkości tekstu w zależności od powyższych czynników. Jeśli chcesz narysować tło
za tekstem, możesz użyć zmierzonych informacji, aby poznać rozmiar
obszar, który zajmuje tekst:
val textMeasurer = rememberTextMeasurer() Spacer( modifier = Modifier .drawWithCache { val measuredText = textMeasurer.measure( AnnotatedString(longTextSample), constraints = Constraints.fixedWidth((size.width * 2f / 3f).toInt()), style = TextStyle(fontSize = 18.sp) ) onDrawBehind { drawRect(pinkColor, size = measuredText.size.toSize()) drawText(measuredText) } } .fillMaxSize() )
Ten fragment kodu powoduje wyświetlenie różowego tła tekstu:

Zmiana ograniczeń, rozmiaru czcionki lub dowolnej właściwości wpływającej na zmierzony rozmiar powoduje zgłoszenie nowego rozmiaru. Możesz ustawić stały rozmiar zarówno dla: width
,
i height
, a tekst – tak jak w polu TextOverflow
. Na przykład poniższy kod renderuje tekst na wysokości ⅓ i szerokości ⅓ obszaru kompozycyjnego oraz ustawia wartość TextOverflow
na TextOverflow.Ellipsis
:
val textMeasurer = rememberTextMeasurer() Spacer( modifier = Modifier .drawWithCache { val measuredText = textMeasurer.measure( AnnotatedString(longTextSample), constraints = Constraints.fixed( width = (size.width / 3f).toInt(), height = (size.height / 3f).toInt() ), overflow = TextOverflow.Ellipsis, style = TextStyle(fontSize = 18.sp) ) onDrawBehind { drawRect(pinkColor, size = measuredText.size.toSize()) drawText(measuredText) } } .fillMaxSize() )
Tekst jest teraz rysowany w ograniczeniach z wielokropkiem na końcu:

TextOverflow.Ellipsis
z ograniczeniami dotyczącymi pomiaru tekstu.Rysowanie obrazu
Aby narysować wzór ImageBitmap
przy użyciu: DrawScope
, wczytaj obraz za pomocą
ImageBitmap.imageResource()
, a następnie zadzwoń pod numer drawImage
:
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) Canvas(modifier = Modifier.fillMaxSize(), onDraw = { drawImage(dogImage) })

ImageBitmap
w Canvas.Narysuj kształty podstawowe
W DrawScope
jest wiele funkcji rysowania kształtów. Aby narysować kształt, użyj jednej z wstępnie zdefiniowanych funkcji rysowania, takich jak drawCircle
:
val purpleColor = Color(0xFFBA68C8) Canvas( modifier = Modifier .fillMaxSize() .padding(16.dp), onDraw = { drawCircle(purpleColor) } )
Interfejs API |
Urządzenie wyjściowe |
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
Narysuj ścieżkę
Ścieżka to seria instrukcji matematycznych, która po wykonaniu tworzy rysunek. DrawScope
może narysować ścieżkę za pomocą metody DrawScope.drawPath()
.
Załóżmy, że chcesz narysować trójkąt. Możesz wygenerować ścieżkę za pomocą funkcji
takie jak lineTo()
i moveTo()
, korzystając z rozmiaru obszaru rysowania.
Następnie wywołaj funkcję drawPath()
, używając tej nowo utworzonej ścieżki, aby uzyskać trójkąt.
Spacer( modifier = Modifier .drawWithCache { val path = Path() path.moveTo(0f, 0f) path.lineTo(size.width / 2f, size.height / 2f) path.lineTo(size.width, 0f) path.close() onDrawBehind { drawPath(path, Color.Magenta, style = Stroke(width = 10f)) } } .fillMaxSize() )

Path
w Compose.Dostęp do obiektu Canvas
DrawScope
nie zapewnia bezpośredniego dostępu do obiektu Canvas
. Możesz użyć DrawScope.drawIntoCanvas()
, aby uzyskać dostęp do obiektu Canvas
, którego możesz używać do wywoływania funkcji.
Jeśli na przykład masz niestandardowy obiekt Drawable
, który chcesz narysować na
możesz uzyskać dostęp do obszaru roboczego i wywołać funkcję Drawable#draw()
, przekazując
Obiekt Canvas
:
val drawable = ShapeDrawable(OvalShape()) Spacer( modifier = Modifier .drawWithContent { drawIntoCanvas { canvas -> drawable.setBounds(0, 0, size.width.toInt(), size.height.toInt()) drawable.draw(canvas.nativeCanvas) } } .fillMaxSize() )

Drawable
.Więcej informacji
Więcej informacji o rysowaniu w funkcji Compose znajdziesz w tych artykułach: zasoby:
- Modyfikatory graficzne – poznaj różne rodzaje rysowania. modyfikatory.
- Pędzel – dowiedz się, jak dostosować malowanie treści.
- Niestandardowe układy i grafika w usłudze Compose – Android Dev Summit 2022 – dowiedz się, jak utworzyć niestandardowy interfejs użytkownika w usłudze Compose za pomocą układów oraz Grafika.
- Przykład JetLagged – przykładowy projekt pokazujący, jak narysować wykres niestandardowy.
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Modyfikatory graficzne
- Grafika w funkcji tworzenia wiadomości
- Linia wyrównania w Jetpack Compose