ConstraintLayout
to układ, który umożliwia umieszczanie komponentów względem innych komponentów na ekranie. Jest to alternatywa dla korzystania z wielu zagnieżdżonych elementów Row
, Column
, Box
i innych elementów układu niestandardowego. ConstraintLayout
jest przydatny w przypadku implementacji większych układów z bardziej skomplikowanymi wymaganiami dotyczącymi wyrównywania.
Możesz użyć ConstraintLayout
w tych sytuacjach:
- Aby uniknąć zagnieżdżania elementów
Column
iRow
w celu pozycjonowania elementów na ekranie i poprawienia czytelności kodu. - Pozycjonowanie elementów względem innych elementów lub elementów na podstawie linii pomocniczych, barier lub łańcuchów.
W systemie widoków widok ConstraintLayout
był zalecanym sposobem tworzenia dużych i złożonych układów, ponieważ płaska hierarchia widoków zapewniała lepszą wydajność niż widoki zagnieżdżone. W Compose nie ma to jednak znaczenia, ponieważ to narzędzie może skutecznie obsługiwać głębokie hierarchie układu.
Rozpocznij korzystanie z usługi ConstraintLayout
Aby używać funkcji ConstraintLayout
w funkcji tworzenia wiadomości, musisz dodać tę zależność w build.gradle
(oprócz konfiguracji tworzenia wiadomości):
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
ConstraintLayout
w sekcji Komponuj działa w następujący sposób za pomocą języka:
- Utwórz odwołania do każdego elementu w komponentach za pomocą funkcji
createRefs()
lubcreateRefFor()
.ConstraintLayout
- Ograniczenia są dostarczane za pomocą modyfikatora
constrainAs()
, który wykorzystuje odwołanie jako parametr i umożliwia określenie jego ograniczeń w obiekcie lambda. - Ograniczenia są określane za pomocą metody
linkTo()
lub innych przydatnych metod. parent
to istniejące odwołanie, które może służyć do określania ograniczeń dotyczących samego elementu kompozycyjnegoConstraintLayout
.
Oto przykład kompozytowa używającego właściwości ConstraintLayout
:
@Composable fun ConstraintLayoutContent() { ConstraintLayout { // Create references for the composables to constrain val (button, text) = createRefs() Button( onClick = { /* Do something */ }, // Assign reference "button" to the Button composable // and constrain it to the top of the ConstraintLayout modifier = Modifier.constrainAs(button) { top.linkTo(parent.top, margin = 16.dp) } ) { Text("Button") } // Assign reference "text" to the Text composable // and constrain it to the bottom of the Button composable Text( "Text", Modifier.constrainAs(text) { top.linkTo(button.bottom, margin = 16.dp) } ) } }
Ten kod ogranicza górną część elementu Button
do elementu nadrzędnego z marginesem wynoszącym 16.dp
i Text
na dole elementu Button
, a także z marżą równą 16.dp
.
Decoupled API
W przykładzie ConstraintLayout
ograniczenia są określone w tekście, a modyfikator znajduje się w składanym elemencie, do którego są stosowane. Są jednak sytuacje, w których lepiej jest odłączyć ograniczenia od układów, do których się odnoszą. Możesz np. zmienić ograniczenia na podstawie konfiguracji ekranu lub animować przejście między 2 zestawami ograniczeń.
W takich przypadkach możesz użyć ConstraintLayout
w inny sposób:
- Przekaż
ConstraintSet
jako parametr doConstraintLayout
. - Przypisz odwołania utworzone w
ConstraintSet
do elementów kompozycyjnych, używając modyfikatoralayoutId
.
@Composable fun DecoupledConstraintLayout() { BoxWithConstraints { val constraints = if (minWidth < 600.dp) { decoupledConstraints(margin = 16.dp) // Portrait constraints } else { decoupledConstraints(margin = 32.dp) // Landscape constraints } ConstraintLayout(constraints) { Button( onClick = { /* Do something */ }, modifier = Modifier.layoutId("button") ) { Text("Button") } Text("Text", Modifier.layoutId("text")) } } } private fun decoupledConstraints(margin: Dp): ConstraintSet { return ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") constrain(button) { top.linkTo(parent.top, margin = margin) } constrain(text) { top.linkTo(button.bottom, margin) } } }
Gdy trzeba zmienić ograniczenia, możesz po prostu podać inną wartość parametru ConstraintSet
.
ConstraintLayout
pojęcia
ConstraintLayout
zawiera takie elementy jak linie pomocnicze, bariery i łańcuchy, które mogą pomóc w pozycjonowaniu elementów w komponowalnym.
Wskazówki
Wskazówki to małe wizualne pomoce ułatwiające projektowanie układów. Elementy składane mogą być ograniczone do jednej wskazówki. Wskazówki są przydatne przy pozycjonowaniu elementów w określonym elemencie dp
lub percentage
w nadrzędnym elemencie kompozycyjnym.
Istnieją 2 rodzaje wytycznych: pionowe i poziome. Te 2 poziome to top
i bottom
, a dwie pionowe to start
i end
.
ConstraintLayout { // Create guideline from the start of the parent at 10% the width of the Composable val startGuideline = createGuidelineFromStart(0.1f) // Create guideline from the end of the parent at 10% the width of the Composable val endGuideline = createGuidelineFromEnd(0.1f) // Create guideline from 16 dp from the top of the parent val topGuideline = createGuidelineFromTop(16.dp) // Create guideline from 16 dp from the bottom of the parent val bottomGuideline = createGuidelineFromBottom(16.dp) }
Aby utworzyć wytyczne, użyj instrukcji createGuidelineFrom*
z odpowiednim typem wytycznych. Spowoduje to utworzenie odwołania, którego można użyć w bloku Modifier.constrainAs()
.
Przeszkody
Bariery odwołują się do wielu elementów kompozycyjnych, aby utworzyć wirtualne wytyczne oparte na najbardziej ekstremalnym widżecie po określonej stronie.
Aby utworzyć barierę, użyj właściwości createTopBarrier()
(lub: createBottomBarrier()
, createEndBarrier()
, createStartBarrier()
) i podaj odniesienia, które powinny stanowić barierę.
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val topBarrier = createTopBarrier(button, text) } }
Barierę można potem wykorzystać w bloku Modifier.constrainAs()
.
Łańcuchy
Łańcuchy zapewniają działanie podobne do działania grup w jednej osi (poziomej lub pionowej). Druga oś może być ograniczona niezależnie.
Aby utworzyć łańcuch, użyj createVerticalChain
lub createHorizontalChain
:
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val verticalChain = createVerticalChain(button, text, chainStyle = ChainStyle.Spread) val horizontalChain = createHorizontalChain(button, text) } }
Łańcucha można następnie użyć w bloku Modifier.constrainAs()
.
Łańcuch można skonfigurować za pomocą różnych ChainStyles
, które określają sposób obsługi przestrzeni otaczającej kompozyt, np.:
ChainStyle.Spread
: przestrzeń jest rozłożona równomiernie na wszystkie elementy, w tym wolna przestrzeń przed pierwszym elementem i po ostatnim.ChainStyle.SpreadInside
: przestrzeń jest rozłożona równomiernie na wszystkie elementy, bez wolnej przestrzeni przed pierwszym elementem i po ostatnim.ChainStyle.Packed
: przestrzeń jest rozłożona przed pierwszym i po ostatnim składanym, a składane są ułożone obok siebie bez żadnych odstępów.
Więcej informacji
Dowiedz się więcej o interfejsie ConstraintLayout
w Compose, korzystając z interfejsów API w praktyce w przykładach Compose, które korzystają z interfejsu ConstraintLayout
.
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Zaznacz w oknie tworzenia wiadomości
- Kotlin w Jetpack Compose
- Podstawy tworzenia układu