I just created a simple Composable and wished to render it using a Layout, but while implementing the solution, I stumbled upon this error in the measurement phase.
java.lang.IllegalArgumentException: Can't represent a size of 214748364 in Constraints
at androidx.compose.ui.unit.Constraints$Companion.bitsNeedForSize(Constraints.kt:408)
at androidx.compose.ui.unit.Constraints$Companion.createConstraints-Zbe2FdA$ui_unit_release(Constraints.kt:368)
at androidx.compose.ui.unit.ConstraintsKt.Constraints(Constraints.kt:438)
at androidx.compose.ui.unit.ConstraintsKt.Constraints$default(Constraints.kt:423)
at com.gmarsk.aiare.MainActivity$InstructionsScreen$DisplayCard$1.measure-3p2s80s(MainActivity.kt:514)
at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:54)
This was when I tried this
val sampleComposable = measurables[1].measure(
Constraints(
minHeight = constraints.maxHeight * 7 / 10,
)
)
Anyone stumble upon this before? What's the solution if it is not a bug, in which case please let me know.
Now, the issue here I think is the fact that I am nesting two Layout Composables,
Layout(
content = {
Dummy1()
Dummy2()
NestedLayoutComposable() // It contains a Layout Composable itself
}{ measurables, constraints ->
val nlc = measurables[2].measure(
Constraints(
minHeight = constraints.maxHeight * 7/10
)
)
layout(constraints.maxWidth, constraints.maxHeight){
nls.place(0, 0)
}
}
)
Where The nestedLayoutComposable again has a Layout and that is where the crash occurs, it is at this line
Layout(
content = {
Text(text = "Random")
Box {
Image(painter = AppUtils.getRandomImagePainter(), contentDescription = "")
}
}
) { measurables, constraints ->
val text = measurables[0].measure(constraints)
/*This line -->*/ val image = measurables[1].measure(
Constraints(
maxWidth = constraints.maxWidth * 90 / 100,
minHeight = constraints.maxHeight * 7 / 10
)
)
layout(constraints.maxWidth, constraints.maxHeight) {
instruction.place(
(constraints.maxWidth - instruction.width) / 2,
0
)
illustration.place(
(constraints.maxWidth - illustration.width) / 2,
illustration.height / 2
)
}
}
So I know that the issue is with the Layout Composable being nested within one another but that still doesn't explain WHY the error occurs, and HOW to resolve it, and so those are the prime queries of this post, and that is what I expect the answers to include, thank you.
In your case it's because you can't measure anything with multipliers of Constraints.Infinity. Because in source code of createConstraints function
internal fun createConstraints(
minWidth: Int,
maxWidth: Int,
minHeight: Int,
maxHeight: Int
): Constraints {
// 🔥 Because of this check and bitsNeedForSize
val heightVal = if (maxHeight == Infinity) minHeight else maxHeight
val heightBits = bitsNeedForSize(heightVal)
val widthVal = if (maxWidth == Infinity) minWidth else maxWidth
val widthBits = bitsNeedForSize(widthVal)
}
converts heightVal to 0 when passed height is Constraints.Infinity when you modify it you send a value to bitsNeedForSize that overflows maxrange and it crashes with
private fun bitsNeedForSize(size: Int): Int {
return when {
size < MaxNonFocusMask -> MaxNonFocusBits
size < MinNonFocusMask -> MinNonFocusBits
size < MinFocusMask -> MinFocusBits
size < MaxFocusMask -> MaxFocusBits
else -> throw IllegalArgumentException(
"Can't represent a size of $size in " +
"Constraints"
)
}
}
Simple check should be whether the dimension you use is Constraints.Infinity using hasBoundedHeight or constraints.min/maxHieght == Constraints.Infinity
Also another check should be for min constraints not being bigger than maxConstraints so
val wrappedConstraints = constraints.copy(
minHeight = if (constraints.hasBoundedHeight)
(constraints.maxHeight * 7 / 10).coerceAtMost(constraints.maxHeight)
else 0,
)
using such a Constraints to measure your content Composables won't crash.
Also to set your custom layout height if it has a Modifier.fillMaxHeight() or Modifier.height(100) by checking hasFixedHeight and not a infinite with hasBoundedHeight
val contentHeight = // This some height you get with max, sum or your logic
val totalHeight = if(hasBoundedHeight && hasFixedHeight){
constraints.maxHeight
}else {
contentHeight.coerceIn(constraints.minHeight.toFloat(), constraints.maxHeight.toFloat())
}
When it doesn't have a size Modifier or a Modifier with Modifier.height(min=0.dp, max=500.dp)
you say let this Composable as big as content but within range of Constraints from size Modifier.
This check also makes sure your Composable do not crash when intrinsic height modifier is assigned.
java.lang.IllegalArgumentException: Can't represent a size of 2147483647 in Constraints
This basically happens when you jam much more than the composable has room for to display.
I have reproduced it using a very long String for a List item
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With