I'm using Constraint Layout with Compose to make a basic app that adds and subtracts numbers. The functionality works fine, the problem is when I want to add a margin between the elements of the view, that if I add a chainStyle of type Packed, it ignores them:
@Composable
fun CreateStructure() {
var num by rememberSaveable { mutableStateOf(0) }
val constraint = ConstraintSet {
val valueLabel = createRefFor("valueLabel")
val addButton = createRefFor("addButton")
val subtractButton = createRefFor("subtractButton")
val resetButton = createRefFor("resetButton")
constrain(valueLabel) {
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
bottom.linkTo(addButton.top)
}
constrain(addButton) {
top.linkTo(valueLabel.bottom, 30.dp)
start.linkTo(valueLabel.start)
end.linkTo(valueLabel.end)
bottom.linkTo(subtractButton.top)
width = Dimension.value(200.dp)
}
constrain(subtractButton) {
top.linkTo(addButton.bottom, 10.dp)
start.linkTo(addButton.start)
end.linkTo(addButton.end)
bottom.linkTo(resetButton.top)
width = Dimension.fillToConstraints
}
constrain(resetButton) {
top.linkTo(subtractButton.bottom, 10.dp)
start.linkTo(subtractButton.start)
end.linkTo(subtractButton.end)
bottom.linkTo(parent.bottom)
width = Dimension.fillToConstraints
}
createVerticalChain(valueLabel, addButton, subtractButton, resetButton, chainStyle = ChainStyle.Packed)
}
ConstraintLayout(constraintSet = constraint, Modifier.fillMaxSize()) {
Text(text = "Conteo: $num", Modifier.layoutId("valueLabel"))
Counter(layoutId = "addButton", titleButton = "Sumar número") {
num++
}
Counter(layoutId = "subtractButton", titleButton = "Restar número") {
num--
}
Counter(layoutId = "resetButton", titleButton = "Resetear valor") {
num = 0
}
}
}
I don't know if being Compose works differently, but using XML I created the views like this and when I added margins to chained views it added it to me without problems, so it's not a Compose bug or it's the behavior it has...
No, it is not a bug but we cannot say that it is different from XML either.
Whether in Kotlin or XML, when you define a chain, constraints going in that direction are replaced. If the chain is horizontal, the
start
and constraints are ignoredend
.top
If you define a VerticalChain, and are ignoredbottom
. Therefore your only constraints that are effectively doing something are theseand that explains the result you see in the image.
The reason it works in XML is because the equivalent of something like that
top.linkTo(valueLabel.bottom, 30.dp)
is two different attributes:So the margin is not affected.
I don't see that your question asks for a solution but in case someone asks, it can be solved by adding spacers in the string
Depending on the direction of the chain, the size of the gap is specified with the modifier
height
owidth
. Although it usuallysize
works for both cases