Wiele aplikacji musi mieć możliwość dokładnego kontrolowania tego, co jest wyświetlane na ekranie. Może to być po prostu umieszczenie ramki czy okręgu we właściwym miejscu albo skomplikowanego układu elementów graficznych w wielu różnych stylach.
Podstawowy rysunek z modyfikatorami i DrawScope
Podstawowym sposobem rysowania elementów niestandardowych w funkcji Utwórz jest modyfikatory, takie jak Modifier.drawWithContent
, Modifier.drawBehind
i Modifier.drawWithCache
.
Jeśli na przykład chcesz narysować coś za elementem kompozycyjnym, możesz użyć modyfikatora drawBehind
, aby rozpocząć wykonywanie poleceń rysowania:
Spacer( modifier = Modifier .fillMaxSize() .drawBehind { // this = DrawScope } )
Jeśli potrzebujesz jedynie funkcji kompozycyjnej, która rysuje, możesz użyć funkcji Canvas
. Funkcja kompozycyjna Canvas
to wygodny sposób opakowania Modifier.drawBehind
. Element Canvas
umieszczasz w układzie w taki sam sposób jak każdy inny element interfejsu Compose. W obrębie Canvas
możesz rysować elementy z precyzyjną kontrolą nad ich stylem i lokalizacją.
Wszystkie modyfikatory rysowania ujawniają DrawScope
– środowisko rysowania o zakresie ograniczonym, które zachowuje własny stan. Pozwala to ustawić parametry grupy elementów graficznych. Pole DrawScope
zawiera kilka przydatnych pól, np. size
, obiekt Size
, który określa bieżące wymiary obiektu DrawScope
.
Aby coś narysować, możesz skorzystać z jednej z wielu funkcji rysowania na ekranie DrawScope
. Na przykład ten kod rysuje prostokąt w lewym górnym rogu ekranu:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F drawRect( color = Color.Magenta, size = canvasQuadrantSize ) }
Więcej informacji o różnych modyfikatorach rysunków znajdziesz w dokumentacji modyfikatorów graficznych.
Układ współrzędnych
Aby narysować coś na ekranie, musisz znać przesunięcie (x
i y
) oraz rozmiar elementu. W przypadku wielu metod rysowania w DrawScope
położenie i rozmiar są określane przez domyślne wartości parametrów. Parametry domyślne zazwyczaj ustawiają element w punkcie [0, 0]
w obszarze roboczym i udostępniają domyślny element (size
), który wypełnia cały obszar rysowania, jak w przykładzie powyżej. Jak widać w powyższym przykładzie, prostokąt jest umieszczony w lewym górnym rogu. Aby móc dostosowywać rozmiar i pozycję elementu, musisz znać jego układ współrzędnych.
Punkt początkowy układu współrzędnych ([0,0]
) znajduje się w lewym górnym rogu piksela w obszarze rysowania. x
zwiększa się, gdy porusza się w prawo, a y
w miarę przesuwania się w dół.
Jeśli na przykład chcesz narysować ukośną linię od prawego górnego rogu obszaru roboczego do lewego dolnego rogu, możesz użyć funkcji DrawScope.drawLine()
i określić przesunięcie początku i końca, podając 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 ) }
Podstawowe przekształcenia
DrawScope
udostępnia przekształcenia pozwalające zmienić miejsce i sposób wykonywania poleceń rysowania.
Skala
Użyj narzędzia DrawScope.scale()
, aby według współczynnika zwiększyć rozmiar operacji rysowania. Operacje takie jak scale()
mają zastosowanie do wszystkich operacji rysowania w odpowiednim obiekcie lambda. Na 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()) } }
Tłumacz
Użyj DrawScope.translate()
, aby przenosić operacje rysowania w górę, w dół, w lewo lub w prawo. Na przykład ten kod przenosi 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 narzędzia DrawScope.rotate()
, aby obracać operacje rysowania wokół punktu obrotu. Na przykład 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 ) } }
Odcięcie
Użyj DrawScope.inset()
, aby dostosować domyślne parametry bieżącego obiektu DrawScope
, zmieniając granice rysowania i zmieniając jego położenie na rysunkach:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F inset(horizontal = 50f, vertical = 30f) { drawRect(color = Color.Green, size = canvasQuadrantSize) } }
Ten kod skutecznie dodaje dopełnienie do poleceń rysowania:
Wiele przekształceń
Aby zastosować do rysunków wiele przekształceń, użyj funkcji DrawScope.withTransform()
, która utworzy i zastosuje jedno przekształcenie łączące wszystkie niezbędne zmiany. Korzystanie z funkcji withTransform()
jest wydajniejsze niż generowanie zagnieżdżonych wywołań poszczególnych przekształceń, ponieważ wszystkie te przekształcenia są wykonywane razem w ramach jednej operacji, a nie w ramach tworzenia trzeba obliczać i zapisywać każde z zagnieżdżonych przekształceń.
Na przykład ten kod stosuje do prostokąta zarówno translację, jak i obró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 ) } }
Typowe operacje rysowania
Narysuj tekst
Aby rysować tekst w sekcji Utwórz, zwykle możesz używać funkcji kompozycyjnej Text
. Jeśli jednak używasz DrawScope
lub chcesz narysować tekst ręcznie, korzystając z dostosowywania, możesz użyć metody DrawScope.drawText()
.
Aby narysować tekst, utwórz TextMeasurer
przy użyciu rememberTextMeasurer
i wywołaj drawText
za pomocą miarki:
val textMeasurer = rememberTextMeasurer() Canvas(modifier = Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello") }
Mierzenie tekstu
Rysowanie tekstu działa trochę inaczej niż inne polecenia rysowania. Normalnie, przekazujesz poleceniem rysunkowym rozmiar (szerokość i wysokość), by narysować kształt lub obraz. W przypadku tekstu jest kilka parametrów, które kontrolują rozmiar renderowanego tekstu, np. rozmiar czcionki, czcionka, ligatury i odstępy między literami.
Za pomocą funkcji TextMeasurer
możesz uzyskać dostęp do zmierzonego rozmiaru tekstu (w zależności od powyższych czynników). Jeśli chcesz narysować tło za tekstem, możesz użyć informacji zmierzonych, aby określić rozmiar obszaru, na jaki 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 tworzy różowe tło tekstu:
Jeśli zmienisz ograniczenia, rozmiar czcionki lub dowolną właściwość, która ma wpływ na mierzony rozmiar, spowoduje to utworzenie nowego rozmiaru w raporcie. Możesz ustawić stały rozmiar dla width
i height
. Tekst będzie się wyświetlać zgodnie z tym ustawieniem TextOverflow
. Na przykład ten kod renderuje tekst na 1⁄3 wysokości i 1⁄3 szerokości obszaru kompozycyjnego, a 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 narysowany w ramach ograniczeń i znajduje się na końcu wielokropka:
Narysuj obraz
Aby narysować element ImageBitmap
z użyciem DrawScope
, wczytaj obraz za pomocą metody ImageBitmap.imageResource()
, a następnie wywołaj drawImage
:
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) Canvas(modifier = Modifier.fillMaxSize(), onDraw = { drawImage(dogImage) })
Narysuj podstawowe kształty
Aplikacja DrawScope
zawiera wiele funkcji rysowania kształtów. Aby narysować kształt, użyj jednej ze wstępnie zdefiniowanych funkcji rysowania, np. drawCircle
:
val purpleColor = Color(0xFFBA68C8) Canvas( modifier = Modifier .fillMaxSize() .padding(16.dp), onDraw = { drawCircle(purpleColor) } )
Interfejs API |
Odpowiedź |
Narysuj ścieżkę
Ścieżka to seria instrukcji matematycznych, których efektem jest jeden rysunek. DrawScope
może narysować ścieżkę, używając metody DrawScope.drawPath()
.
Załóżmy, że chcesz narysować trójkąt. Ścieżkę można wygenerować za pomocą funkcji takich jak lineTo()
i moveTo()
, korzystając z rozmiaru obszaru rysowania.
Następnie wywołaj drawPath()
tą nowo utworzoną ścieżką, 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() )
Uzyskuję dostęp do Canvas
obiektu
DrawScope
nie ma bezpośredniego dostępu do obiektu Canvas
. Możesz użyć DrawScope.drawIntoCanvas()
, aby uzyskać dostęp do obiektu Canvas
, w którym możesz wywoływać funkcje.
Jeśli na przykład masz niestandardowy obiekt Drawable
, który chcesz narysować na kanwie, możesz otworzyć obszar roboczy i wywołać 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() )
Więcej informacji
Więcej informacji o rysowaniu w widoku tworzenia wiadomości znajdziesz w tych materiałach:
- Modyfikatory graficzne – dowiedz się więcej o różnych typach modyfikatorów rysunków.
- Pędzel – dowiedz się, jak dostosować sposób malowania treści.
- Niestandardowe układy i grafika w usłudze Compose – Android Dev Summit 2022 – dowiedz się, jak utworzyć własny interfejs w sekcji Composes (Układy i Grafika).
- JetLagged Sample (Próbka JetLagged) – przykład tworzenia wiadomości, który pokazuje, jak narysować niestandardowy wykres.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Modyfikatory graficzne
- Grafika w obszarze tworzenia wiadomości
- Linie wyrównania w Jetpack Compose