ConstraintLayout no Compose (original) (raw)

O ConstraintLayout é um layout que permite posicionar elementos combináveis em relação a outros elementos na tela. Essa é uma alternativa ao uso de vários elementosRow, Column, Box aninhados e outros elementos de layout personalizados.

No sistema de visualização, ConstraintLayout era a maneira recomendada de criar layouts grandes e complexos, já que uma hierarquia de visualização plana era melhor para o desempenho do que as visualizações aninhadas. No entanto, isso não é um problema no Compose, que consegue processar hierarquias de layout profundas com eficiência. Por isso, o ConstraintLayout não é tão benéfico.

Comece a curtir o canal ConstraintLayout

Para usar o ConstraintLayout no Compose, é necessário adicionar essa dependência aobuild.gradle, além da configuração do Compose:

implementation "androidx.constraintlayout:constraintlayout-compose:$constraintlayout_compose_version"

No Compose, o ConstraintLayout funciona da seguinte maneira usando umaDSL:

Veja o exemplo de um elemento de composição usando 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 de16.dp e um Text na parte inferior de Button, também com uma margem de16.dp.

O botão aparece acima do texto

Figura 1. Um elemento combinável Button e um Text restritos um ao outro em umConstraintLayout.

API dissociada

No exemplo de ConstraintLayout, as restrições são especificadas inline, com um modificador no elemento combinável 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:

  1. Transmita um ConstraintSet como um parâmetro para ConstraintLayout.
  2. Atribua referências criadas no ConstraintSet aos elementos combináveis usando o modificador layoutId.

@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 umConstraintSet diferente.

Conceitos de ConstraintLayout

O ConstraintLayout contém conceitos, como diretrizes, barreiras e cadeias, que podem ajudar a posicionar elementos dentro do elemento combinável.

Diretrizes

Diretrizes são pequenos auxiliares visuais para criar layouts. Os elementos de composição podem ser restritos a uma diretriz. Elas são úteis para posicionar elementos em uma determinadadp ou percentage dentro do elemento combinável pai.

Há dois tipos de diretrizes: vertical e horizontal. Os dois horizontais são top e bottom, e os dois verticais são start eend.

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) }

Para criar uma diretriz, use o createGuidelineFrom* com o tipo de diretriz necessário. Isso cria uma referência que pode ser usada no bloco Modifier.constrainAs().

Barreiras

As barreiras referenciam vários elementos combináveis para criar uma diretriz virtual com base no widget mais extremo do lado especificado.

Para criar uma, use createTopBarrier() (ou: createBottomBarrier(),createEndBarrier(), createStartBarrier()) e forneça as referências que precisam compor a barreira.

ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text")

    val topBarrier = createTopBarrier(button, text)
}

}

A barreira pode ser usada em um bloco Modifier.constrainAs().

Cadeias

As cadeias fornecem comportamentos semelhantes a grupos em um único eixo (horizontal ou vertical). O outro eixo pode ser restrito de maneira independente.

Para criar uma cadeia, use createVerticalChain oucreateHorizontalChain:

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 cadeia pode ser usada no bloco Modifier.constrainAs().

Uma cadeia pode ser configurada com diferentes ChainStyles, que decidem como lidar com o espaço ao redor de um elemento combinável, como: