I'm trying to build a custom Column whose children are separated by a divider that's provided to it. The divider should only be applied between children that are actually rendered.
I initially thought of trying to replicate Arrangement.separatedBy() that Column uses, but it doesn't seem possible for my use case. I ended up going with the custom composable approach, and came up with the following implementation, but ran into an issue with measuring the dividers.
Any help/pointers would be appreciated.
@Composable
fun ColumnWithChildrenSeparatedByDivider(
modifier: Modifier = Modifier,
divider: @Composable () -> Unit,
content: @Composable () -> Unit,
) {
Layout(
modifier = modifier,
contents = listOf(content, divider),
) { measurables, constraints ->
val contentPlaceables = measurables.first().map { measurable ->
measurable.measure(constraints)
}
// Only take into account children that will actually be rendered
val contentToRenderCount = contentPlaceables.map { it.width > 0 }.count()
// This crashes, since I can't measure the same measurable more than once
val dividerPlaceables = List(contentToRenderCount - 1) { measurables[1].first().measure(constraints) }
layout(constraints.maxWidth, constraints.maxHeight) {
var yPosition = 0
var dividerIndex = 0
for (contentPlaceable in contentPlaceables) {
if (contentPlaceable.height <= 0) {
continue
}
// Place child
contentPlaceable.place(x = 0, y = yPosition)
yPosition += contentPlaceable.height
// Place divider
val dividerPlaceable = dividerPlaceables[dividerIndex++]
dividerPlaceable.place(x = 0, y = yPosition)
yPosition += dividerPlaceable.height
}
}
}
}
@Composable
fun Divider() {
// Could be anything
}
Even if you were able to measure multiple times with
you wouldn't be able to place same placable that is placed already.
You can either multiply the number of Dividers to match content size with initial number max of available content size such as, i used a fixed number for demonstration.
Usage
Other option is to use single param content: @Composable () -> Unit
then either give Modifier.layoutId() to each content and divider and check those or use modulus for even and odd positions with indexing to match non zero width content with matching divider.
Usage