sindrenm
02/08/2023, 4:36 PMRow
-like that only places the items it can actually fully fit, and that “reports back” on the number of items it was able to place. I came up with something like what I have in the thread, which works great for the fitting part, but it doesn't seem to call the callback with the correct number. I'm sure it's something obvious. Any ideas?@Composable
fun FittingRow(
modifier: Modifier = Modifier,
itemSpacing: Dp = 0.dp,
onPlaced: (numberOfItems: Int) -> Unit = {},
content: @Composable () -> Unit,
) {
Layout(
modifier = modifier.wrapContentSize(),
content = content,
) { measurables, constraints ->
val placeables = measurables.map { it.measure(constraints) }
val maxWidth = constraints.maxWidth
layout(maxWidth, placeables.maxOf { it.height }) {
var xPositionOfNext = 0
var numberOfPlacedItems = 0
placeables.forEach {
if (xPositionOfNext + it.width > maxWidth) {
onPlaced(numberOfPlacedItems)
return@forEach
}
it.place(xPositionOfNext, 0)
numberOfPlacedItems++
xPositionOfNext += it.width + itemSpacing.toPx().toInt()
}
}
}
}
@Composable
private fun Items(items: List<Int>, modifier: Modifier = Modifier) {
Column(
modifier,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
var placedItems by remember { mutableStateOf(0) }
FittingRow(itemSpacing = 0.dp, onPlaced = { placedItems = it }) {
items.forEach { Trophy(it) }
}
Text("Placed items: $placedItems")
}
}
Alex Vanyo
02/08/2023, 4:57 PMplacedItems
as 0
.
If you run that example on a device, you’ll like see Placed items: 0
for a single frame, and then the updated value on the next frame.
That one frame delay is generally something you want to avoid, so I’m curious to hear what onPlaced
is being used forsindrenm
02/08/2023, 8:36 PMValentin Gusselnikov
02/08/2023, 9:54 PMsindrenm
02/09/2023, 7:46 AM