Can anyone explain why `Modifier.widthIn()` might ...
# compose
r
Can anyone explain why
Modifier.widthIn()
might be ignored when used inside
AnimatedContent(Modifier.weight(1f) { ... }
? It is respected when the
AnimatedContent
has no weight modifier, or when using a plain
Box
instead of AnimatedContent
Box(Modifier.weight(1f)):
Copy code
Row(Modifier.size(200.dp)) {
    Box(Modifier.background(Color.Blue).width(50.dp).fillMaxHeight())

    Box(Modifier.weight(1f)) {
        Box(Modifier.background(Color.Green).widthIn(max = 50.dp)) {
            Box(Modifier.fillMaxSize()) // <-- *Is* constrained to 50dp
        }
    }
}
AnimatedContent(Modifier.weight(1f)):
Copy code
Row(Modifier.size(200.dp)) {
    Box(Modifier.background(Color.Blue).width(50.dp).fillMaxHeight())

    val transition = updateTransition(targetState = 1)
    transition.AnimatedContent(Modifier.weight(1f)) {
        Box(Modifier.background(Color.Green).widthIn(max = 50.dp)) {
            Box(Modifier.fillMaxSize()) // <-- Is *not* constrained to 50dp
        }
    }
}
AnimatedContent(Modifier):
Copy code
Row(Modifier.size(200.dp)) {
    Box(Modifier.background(Color.Blue).width(50.dp).fillMaxHeight())

    val transition = updateTransition(targetState = 1)
    transition.AnimatedContent(Modifier) {
        Box(Modifier.background(Color.Green).widthIn(max = 50.dp)) {
            Box(Modifier.fillMaxSize()) // <-- *Is* constrained to 50dp
        }
    }
}
image.png
d
The difference is that
Box
by default doesn't propagate minConstraints, which means the minWidth as the result of the
weight
modifier doesn't get propagated down to the content inside
Box(Modifier.weight(..)) {..}
The
Layout
used by AnimatedContent simply passes the constraints from parent to children without any modification to the constraints, therefore you get the
200.dp
width. If you add
propagateMinConstraints = true
to Box with weight modifier, you'll get the same result
r
@Doris Liu interesting, thanks for the explainer! One thing that's not clear to me still is why not propagating the "min" constraint would cause the inner content to not be constrained to the "max" constraint?
d
That's because the min constraints from the weight modifier (i.e. 200.dp) is greater than the max constraints (i.e. 50.dp) from
widthIn
. The
widthIn
modifier is sort of a soft requirement in that it conforms to (or gets constrained by) the incoming constraints: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]nMain/kotlin/androidx/compose/foundation/layout/Size.kt;l=827 The end result is that the constraints from
widthIn
gets coerced in the range of width constraints of
weight
in this case