Reputation: 340
I have a strange behaviour with jetpack compose row. This is the demo code: display a row with X items and a vertical divider. Colors are for demo purpose :)
@Composable
fun StackOverflowDemo(itemList: List<Int>) {
Row(
modifier = Modifier
.height(IntrinsicSize.Min)
.background(Color.Blue)
.horizontalScroll(rememberScrollState())
) {
itemList.forEach {
Text(
it.toString(),
modifier = Modifier
.background(Color.Yellow)
.padding(horizontal = 4.dp)
)
Divider(
color = Color.Red,
modifier = Modifier
.width(1.dp)
.fillMaxHeight()
)
}
}
}
With few elements (10), this is the result
But with more elements (30), the result is wrong: the row height is not equal to the single item height, and the vertical divider is too high
Why there is such a different behaviour? What is missing in this simple setup?
Upvotes: 2
Views: 646
Reputation: 23894
If you need a emergency workaround, you can use SubcomposeLayout
in order to calculate the max height and use it as Divider
height.
@Composable
fun StackOverflowDemo(itemList: List<Int>) {
Box(
Modifier
.background(Color.Blue)
.horizontalScroll(rememberScrollState())
) {
SubcomposeLayout { constraints ->
// Measuring each Text
val placeables = subcompose("SomeRandomId") {
itemList.forEach {
Text(
it.toString(),
modifier = Modifier
.background(Color.Yellow)
.padding(horizontal = 4.dp)
)
}
}.map { it.measure(constraints) }
// Getting the max height to use in the divider
val maxHeight = placeables.maxOf { it.height }
// Now the Dividers are measured
val dividers = subcompose("SomeDividerId") {
(0 until itemList.lastIndex).map {
Divider(
color = Color.Red,
modifier = Modifier
.height(with(LocalDensity.current) { maxHeight / density }.dp)
.width(1.dp)
)
}
}.map { it.measure(constraints) }
// Calculating the total width of the components
val width = placeables.sumOf { it.width } + dividers.sumOf { it.width }
// Placing Text and dividers into the layout
layout(width, maxHeight) {
var x = 0
placeables.forEachIndexed { index, placeable ->
placeable.placeRelative(x, 0)
x += placeable.width
// the divider is not displayed after the last item
if (index < placeables.lastIndex) {
dividers[index].place(x, 0)
x += dividers[index].width
}
}
}
}
}
}
Here's the result:
Upvotes: 1