You can achieve setting width of long button to short one as in the answer described here with SubcomposeLayout.
What you need to do is subcompose your layout to check which element has longer width then subcompose your items again with this width as minimum constraint.
@Composable
private fun SubcomposeRow(
modifier: Modifier = Modifier,
paddingBetween: Dp = 0.dp,
content: @Composable () -> Unit = {},
) {
val density = LocalDensity.current
SubcomposeLayout(modifier = modifier) { constraints ->
var subcomposeIndex = 0
val spaceBetweenButtons = with(density) {
paddingBetween.roundToPx()
}
var placeables: List<Placeable> = subcompose(subcomposeIndex++, content)
.map {
it.measure(constraints)
}
var maxWidth = 0
var maxHeight = 0
var layoutWidth = 0
placeables.forEach { placeable: Placeable ->
maxWidth = placeable.width.coerceAtLeast(maxWidth)
.coerceAtMost(((constraints.maxWidth - spaceBetweenButtons) / 2))
maxHeight = placeable.height.coerceAtLeast(maxHeight)
}
layoutWidth = maxWidth
// Remeasure every element using width of longest item using it as min width
// Our max width is half of the remaining area after we subtract space between buttons
// and we constraint its maximum width to half width minus space between
if (placeables.isNotEmpty() && placeables.size > 1) {
placeables = subcompose(subcomposeIndex, content).map { measurable: Measurable ->
measurable.measure(
constraints.copy(
minWidth = maxWidth,
maxWidth = ((constraints.maxWidth - spaceBetweenButtons) / 2)
.coerceAtLeast(maxWidth)
)
)
}
layoutWidth = (placeables.sumOf { it.width } + spaceBetweenButtons)
.coerceAtMost(constraints.maxWidth)
maxHeight = placeables.maxOf { it.height }
}
layout(layoutWidth, maxHeight) {
var xPos = 0
placeables.forEach { placeable: Placeable ->
placeable.placeRelative(xPos, 0)
xPos += placeable.width + spaceBetweenButtons
}
}
}
}
you can change this layouWidth with constraints.maxWidth if you want it to occupy available space.
Then, instead of setting them from beginning of Composable you need to have your algorithm for laying them out at 0 y position and x position from beginning of the Composable if you want to have different spacings.
placeable.placeRelative(xPos, 0)
Usage
@Composable
private fun Sample() {
Column(
modifier = Modifier
.fillMaxSize()
.padding(10.dp)
) {
Spacer(modifier = Modifier.height(20.dp))
SubcomposeRow(
modifier = Modifier.background(Color.LightGray).border(3.dp, Color.Green),
paddingBetween = 20.dp
) {
Button(
modifier = Modifier,
onClick = { }
) {
Text("Short")
}
Button(
modifier = Modifier,
onClick = { }
) {
Text("This is a Long")
}
}
Spacer(modifier = Modifier.height(20.dp))
SubcomposeRow(
modifier = Modifier.background(Color.LightGray).border(3.dp, Color.Green),
paddingBetween = 20.dp
) {
Button(
modifier = Modifier,
onClick = { }
) {
Text("Short")
}
Button(
modifier = Modifier,
onClick = { }
) {
Text("This is a Long a button with text")
}
}
}
}
Result
