Mark
11/14/2023, 4:12 PMColumn
composable. How to make sure the second composable is constrained to be the same width as (or not larger than) the first composable arg?
UPDATE: I found a simple solution using ConstraintLayout
(posted in the thread) but is there a better way?
UPDATE2: Actually the ConstraintLayout
didn’t end up working for me, so I wrote a custom layout instead (posted in the thread)Devashish Bala
11/14/2023, 4:13 PMMark
11/14/2023, 4:15 PMModifier
when using slot API?Devashish Bala
11/14/2023, 4:17 PMDevashish Bala
11/14/2023, 4:18 PMMark
11/14/2023, 4:36 PM@Composable
private fun TestPreview(
firstItem: @Composable (Modifier) -> Unit,
secondItem: @Composable (Modifier) -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
firstItem(Modifier)
secondItem(Modifier)
}
}
Devashish Bala
11/14/2023, 4:41 PM@Composable
private fun TestPreview(
firstItem: @Composable () -> Unit,
secondItem: @Composable () -> Unit,
modifier: Modifier = Modifier,
modifierForInnerComposable: Modifier = Modifier
) {
Column(modifier = modifier) {
firstItem(modifierForInnerComposable )
secondItem(modifierForInnerComposable )
}
}
when Calling function
TestPreview(firstItem = {Text(text="My name is")}, secondItem = {Text(text="Devashish Bala")}, modifier = Modifier.width(34.dp), modifierForInnerComposable = Modifier.width(24.dp))
Devashish Bala
11/14/2023, 4:47 PMDevashish Bala
11/14/2023, 4:48 PMMark
11/15/2023, 6:39 AM@Preview(showBackground = true)
@Composable
fun TopAboveBottomPreview() {
TopAboveBottom(
topItem = { modifier ->
Text(
text = "first item",
overflow = TextOverflow.Ellipsis,
maxLines = 1,
modifier = modifier.background(Color.Green),
)
},
bottomItem = { modifier ->
Text(
text = "second long item",
overflow = TextOverflow.Ellipsis,
maxLines = 1,
modifier = modifier.background(Color.Red),
)
},
)
}
@Composable
private fun TopAboveBottom(
topItem: @Composable (Modifier) -> Unit,
bottomItem: @Composable (Modifier) -> Unit,
modifier: Modifier = Modifier,
) {
ConstraintLayout(modifier = modifier) {
val (topItemRef, bottomItemRef) = createRefs()
topItem(
Modifier.constrainAs(topItemRef) {
top.linkTo(parent.top)
}
)
bottomItem(
Modifier.constrainAs(bottomItemRef) {
top.linkTo(topItemRef.bottom)
start.linkTo(topItemRef.start)
end.linkTo(topItemRef.end)
},
)
}
}
Devashish Bala
11/15/2023, 7:20 AMMark
11/15/2023, 12:26 PM@Composable
fun LayoutItemsVerticallyWrappingFirstWidth(
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Layout(
content = content,
modifier = modifier,
) { measurables, constraints ->
val firstWidth = measurables
.firstOrNull()
?.maxIntrinsicWidth(constraints.maxHeight)
?: 0
val itemConstraints = Constraints(
minWidth = 0,
minHeight = 0,
maxWidth = firstWidth,
maxHeight = constraints.maxHeight,
)
val placeables = measurables.map { measurable ->
measurable.measure(itemConstraints)
}
val height = placeables
.sumOf(Placeable::height)
.coerceAtMost(constraints.maxHeight)
layout(width = firstWidth, height = height) {
var yOffset = 0
placeables.forEach { placeable ->
val xOffset = (firstWidth - placeable.width) / 2
placeable.place(xOffset, yOffset)
yOffset += placeable.height
}
}
}
}
@Preview(showBackground = true)
@Composable
private fun LayoutItemsVerticallyPreview() {
LayoutItemsVerticallyWrappingFirstWidth(
modifier = Modifier.background(Color.Yellow),
) {
Text(
text = "first item",
overflow = TextOverflow.Ellipsis,
maxLines = 1,
modifier = Modifier.background(Color.Green),
)
Text(
text = "second longer item",
overflow = TextOverflow.Ellipsis,
maxLines = 1,
modifier = Modifier.background(Color.Red),
)
}
}