https://kotlinlang.org logo
#compose
Title
# compose
a

allan.conda

10/15/2020, 5:15 PM
Copy code
Column(
    Modifier.wrapContentHeight().aspectRatio(1f)
) {
    Icon(asset, Modifier.size(24.dp))
    Text("Action")
}
We expected this to be a square component; Why is Column expanding to the size of its parent? We figured to just use a fixed size to simplify things, I’m just curious why this wasn’t working. And I’m looking to know a solution for this in case we really need more dynamic sizing.
g

Guy Bieber

10/15/2020, 5:37 PM
You can specify Modifier.weight() for rows and columns to force layouts.
z

Zach Klippenstein (he/him) [MOD]

10/15/2020, 5:37 PM
I think what’s going on is: `aspectRatio`’s kdoc says:
Attempts to size the content to match a specified aspect ratio by trying to match one of the incoming constraints in the following order: Constraints.maxWidth, Constraints.maxHeight, Constraints.minWidth, Constraints.minHeight.
Since
wrapContentHeight
doesn’t affect width constraints, and makes min constraints zero (which are ignored by aspectRatio). The incoming
maxWidth
is going to be the width of the parent.
maxWidth
has highest precedence, so that will the first constraint it matches on so, and it will force height to match parent width. Then,
wrapContentHeight
sees that it’s content (the
aspectRatio
) has this height equal to parent width, and will make itself be that same height as well. I don’t think there’s a way to make this work with a single modifier chain.
wrapContentHeight
only allows child to measure with no min width, so it doesn’t actually have an effect here.
aspectRatio
works by reading the incoming constraints and determining size for its children. So there’s no simple way to determine the size of the children, and then pass that measurement result into the
aspectRatio
to adjust, without doing some tricks.
g

Guy Bieber

10/15/2020, 5:40 PM
Specifying a row weight of .8f and a row weight of .2f would divide the parent container into 80% and 20% of the space. I think this is cleaner for scalable layouts.
z

Zach Klippenstein (he/him) [MOD]

10/15/2020, 5:44 PM
I think the only way to make this work dynamically (without a fixed size) is to write a custom layout. Here’s a modifier that works:
Copy code
object ChildAspectRatio : LayoutModifier {
  override fun MeasureScope.measure(
    measurable: Measurable,
    constraints: Constraints
  ): MeasureResult {
    val placeable = measurable.measure(constraints)
    val size = max(placeable.width, placeable.height)
      .let { constraints.constrain(IntSize(it, it)) }
    return layout(size.width, size.height) {
      placeable.placeRelative(0, 0)
    }
  }
}
a

allan.conda

10/15/2020, 6:59 PM
Thanks @Zach Klippenstein (he/him) [MOD]. We came up with the same conclusion basically. It looks like it would just work however, before looking at the docs. Wondering whether an Android View ConstraintLayout with wrap content and constraintRatio would have the same problem… I should try that, just to satisfy my curiosity
4 Views