jhiertz
05/02/2023, 9:50 AMBoxWithConstraint { }
inside a Column
with Modifier.width(IntrinsicSize.Min)
I'm currently working on a chat feature in my Jetpack Compose app and I'm trying to create a chat bubble that has a minimum size but can expand to almost the entire size of the parent, depending on the content of the message. Within this chat bubble, there can be several composables that will take up the maximum size of the parent without making it bigger.
Could anyone please help me understand how I can achieve this behavior with Jetpack Compose? I'm not sure how to use the available modifiers to make the chat bubble adapt to the content while respecting the minimum size.
I tried with the modifier Modifier.width(IntrinsicSize.Min)
and it works unless there is a child using BoxWithConstraint
. I've got the error:
java.lang.IllegalStateException: Asking for intrinsic measurements of SubcomposeLayout layouts is not supported.Unfortunately, it's a 3rd party library that uses this component and I can't remove it. Is there a workaround I can use to achieve the same result? Thank you in advance for your help!
jhiertz
05/02/2023, 9:51 AMclass MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
Surface(modifier = Modifier.fillMaxSize(), color = Color.White) {
Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
ChatBubble()
ChatBubble()
ChatBubble()
}
}
}
}
}
}
@Composable
fun ChatBubble() {
Surface(
modifier = Modifier
.wrapContentSize()
.defaultMinSize(minWidth = 150.dp, minHeight = 36.dp)
.padding(5.dp),
color = Color.LightGray,
shape = RoundedCornerShape(percent = 10)
) {
Column(
modifier = Modifier
.width(IntrinsicSize.Min)
.widthIn(min = 150.dp),
verticalArrangement = Arrangement.Center
) {
Text(text = "Opt header text", modifier = Modifier.background(Color.Red).fillMaxWidth())
Text(text = "Content body", modifier = Modifier.background(Color.Cyan).fillMaxWidth())
Text(text = randomString())
// BoxWithConstraints { }
}
}
}
val charPool : List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
fun randomString() = (1..Random.nextInt(0, 60))
.map { Random.nextInt(0, charPool.size).let { charPool[it] } }
.joinToString("")
Albert Chang
05/02/2023, 12:20 PMBoxWithConstraints
needs the incoming constraints to decide its content, including its size, and the parent needs the sizes of its children, including the BoxWithConstraints
, to decide the autual constraints used to measure them.Albert Chang
05/02/2023, 12:22 PMBoxWithConstraints
? If it can be ignored in minimum size calculation, you can write a custom layout that excludes it from intrinsic size queries.jhiertz
05/02/2023, 12:29 PMAlbert Chang
05/02/2023, 12:38 PMjhiertz
05/02/2023, 2:21 PMZach Klippenstein (he/him) [MOD]
05/02/2023, 4:48 PMjhiertz
05/03/2023, 7:20 AMBoxWithConstraints
but a Layout
.