ConstraintLayout
pode ajudar a posicionar as funções que podem ser compostas em relação a outras na tela. Essa é uma
alternativa ao uso de várias Row
, Column
e Box
aninhadas e de elementos de layouts
personalizados. ConstraintLayout
é útil para implementar layouts maiores com requisitos de alinhamento
mais complicados.
Para usar ConstraintLayout
no Compose, é necessário adicionar esta dependência ao
build.gradle
:
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02"
No Compose, ConstraintLayout
funciona com uma DSL (link em inglês):
- As referências são criadas usando
createRefs()
oucreateRefFor()
, e cada função que pode ser composta emConstraintLayout
precisa ter uma referência associada a ela. - As restrições são fornecidas usando o modificador
constrainAs()
, que usa a referência como um parâmetro e permite especificar as restrições no lambda do corpo. - As restrições são especificadas usando
linkTo()
ou outros métodos úteis. parent
é uma referência já existente que pode ser usada para especificar restrições no próprioConstraintLayout
que pode ser composto.
Veja um exemplo de elemento que pode ser composto usando um 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)
})
}
}
Esse código restringe o topo do Button
ao pai com uma margem de
16.dp
e um Text
na parte inferior de Button
, também com uma margem de
16.dp
.
Para ver mais exemplos de como trabalhar com ConstraintLayout
, consulte o codelab
de layouts.
API dissociada
No exemplo do ConstraintLayout
,
as restrições são especificadas in-line, com um modificador na função que pode ser composta
a que elas são aplicadas. No entanto, há situações em que é preferível dissociar as restrições dos layouts aos
que elas se aplicam. Por exemplo, talvez você queira
mudar as restrições com base na configuração da tela ou colocar uma animação entre dois
conjuntos de restrições.
Para casos como esses, é possível usar ConstraintLayout
de uma maneira diferente:
- Transmita um
ConstraintSet
como um parâmetro paraConstraintLayout
. - Atribua referências criadas no
ConstraintSet
aos elementos que podem ser compostos usando o modificadorlayoutId
.
@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)
}
}
}
Assim, quando precisar mudar as restrições, basta transmitir um
ConstraintSet
diferente.
Saiba mais
Saiba mais sobre o ConstraintLayout no Compose na seção Layout restrito
do codelab de Layouts no Jetpack Compose
e veja as APIs em ação nos
exemplos do Compose que usam ConstraintLayout
(link em inglês).