W interfejsie Compose elementy interfejsu są reprezentowane przez funkcje kompozycyjne, które po wywołaniu emitują fragment interfejsu, który jest następnie dodawany do drzewa interfejsu, który jest renderowany na ekranie. Każdy element interfejsu ma 1 element nadrzędny i potencjalnie wiele elementów podrzędnych. Każdy element znajduje się też w swoim elemencie nadrzędnym (określonym za pomocą elementów (x, y)) oraz rozmiaru, który określa się za pomocą atrybutów width
i height
.
Elementy nadrzędne określają ograniczenia dotyczące ich elementów podrzędnych. Należy definiować
jego rozmiar w ramach tych ograniczeń. Ograniczenia określają minimalne i maksymalne wartości width
i height
elementu. Jeśli element ma elementy podrzędne,
może mierzyć rozmiar każdego elementu podrzędnego, Gdy element określi i zgłosi własny rozmiar, może określić sposób umieszczania jego elementów podrzędnych względem siebie. Szczegółowe informacje na ten temat znajdziesz w sekcji Tworzenie układów niestandardowych.
Układ każdego węzła w drzewie UI to proces trzyetapowy. Każdy węzeł musi:
- Mierz dane dotyczące elementów podrzędnych
- Wybór własnego rozmiaru
- Umieść elementy podrzędne
Użycie zakresów określa, kiedy możesz mierzyć i umieszczać dzieci.
Pomiar układu można przeprowadzać tylko podczas przekazywania pomiarów i układu, a element podrzędny można umieszczać tylko podczas przebiegu układu (i dopiero po jego zmierzeniu). Ze względu na zakresy tworzenia, takie jak MeasureScope
i PlacementScope
, jest to wymuszane podczas kompilacji.
Korzystanie z modyfikatora układu
Korzystając z modyfikatora layout
, możesz zmienić sposób pomiaru i układu elementu. Layout
to funkcja lambda. Jej parametry obejmują element, który można mierzyć (przekazywany jako measurable
), oraz przychodzące ograniczenia funkcji kompozycyjnej przekazywane jako constraints
. Niestandardowy modyfikator układu może wyglądać tak:
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
Wyświetlmy Text
na ekranie i określ odległość od góry do punktu odniesienia pierwszego wiersza tekstu. Właśnie tak działa modyfikator paddingFromBaseline
– wprowadzamy go tutaj jako przykład.
Aby to zrobić, użyj modyfikatora layout
, aby ręcznie umieścić na ekranie funkcję kompozycyjną. Oto oczekiwane działanie, gdzie Text
dopełnienie u góry jest ustawione 24.dp
:
Oto kod, który utworzy odstępy:
fun Modifier.firstBaselineToTop( firstBaselineToTop: Dp ) = layout { measurable, constraints -> // Measure the composable val placeable = measurable.measure(constraints) // Check the composable has a first baseline check(placeable[FirstBaseline] != AlignmentLine.Unspecified) val firstBaseline = placeable[FirstBaseline] // Height of the composable with padding - first baseline val placeableY = firstBaselineToTop.roundToPx() - firstBaseline val height = placeable.height + placeableY layout(placeable.width, height) { // Where the composable gets placed placeable.placeRelative(0, placeableY) } }
Oto, co się dzieje w tym kodzie:
- W parametrze lambda
measurable
mierzysz wartośćText
reprezentowaną przez parametr wymierny, wywołując metodęmeasurable.measure(constraints)
. - Aby określić rozmiar funkcji kompozycyjnej, wywołaj metodę
layout(width, height)
, która daje również funkcję lambda używaną do umieszczania elementów opakowanych. W tym przypadku jest to wysokość między ostatnią podstawą a dodanym górnym dopełnieniem. - Aby umieścić opakowane elementy na ekranie, wywołaj
placeable.place(x, y)
. Jeśli opakowane elementy nie zostaną umieszczone, nie będą widoczne. Pozycjay
odpowiada górnego dopełnieniu, czyli pozycji pierwszej linii bazowej tekstu.
Aby sprawdzić, czy wszystko działa zgodnie z oczekiwaniami, użyj tego modyfikatora na Text
:
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }
Tworzenie układów niestandardowych
Modyfikator layout
zmienia tylko funkcję wywoływania funkcji kompozycyjnej. Aby mierzyć i układać wiele elementów kompozycyjnych, użyj funkcji Layout
kompozycyjnej. Ten element kompozycyjny umożliwia
ręczne mierzenie i rozmieszczanie elementów dzieci. Wszystkie układy wyższego poziomu, takie jak Column
i Row
, są tworzone za pomocą funkcji kompozycyjnej Layout
.
Utwórzmy podstawową wersję Column
. Większość układów niestandardowych
stosuje się do tego wzorca:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
Podobnie jak modyfikator layout
, measurables
to lista elementów podrzędnych, które mają być objęte pomiarem, a constraints
to ograniczenia elementu nadrzędnego.
Zgodnie z tą samą logiką co wcześniej, element MyBasicColumn
można wdrożyć w ten sposób:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
Podrzędne elementy kompozycyjne są objęte ograniczeniami Layout
(bez ograniczeń minHeight
) i są rozmieszczane na podstawie funkcji yPosition
poprzedniego elementu kompozycyjnego.
Oto jak zostanie użyty niestandardowy element kompozycyjny:
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }
Kierunek układu
Aby zmienić kierunek układu elementu kompozycyjnego, zmień lokalną kompozycję LocalLayoutDirection
.
Jeśli umieszczasz elementy kompozycyjne ręcznie na ekranie, element LayoutDirection
jest częścią LayoutScope
modyfikatora layout
lub funkcji Layout
.
Jeśli używasz layoutDirection
, umieszczaj kompozycje za pomocą place
. W przeciwieństwie do metody placeRelative
parametr place
nie zmienia się zgodnie z kierunkiem układu (od lewej do prawej lub od prawej do lewej).
Układy niestandardowe w działaniu
Więcej informacji o układach i modyfikatorach znajdziesz w sekcji o podstawowych układach w obszarze tworzenia wiadomości, a w sekcji o przykładach tworzenia układów niestandardowych dowiesz się, jak działają układy niestandardowe.
Więcej informacji
Więcej informacji o układach niestandardowych w sekcji Utwórz znajdziesz w tych dodatkowych materiałach.
Filmy
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Pomiary wewnętrzne w układach tworzenia wiadomości
- Grafika w obszarze tworzenia wiadomości
- Modyfikatory tworzenia wiadomości