Skip to content

Instantly share code, notes, and snippets.

@fvilarino
Last active July 27, 2023 15:36
Show Gist options
  • Save fvilarino/da067aca6f079e720e07d9f2a76b2315 to your computer and use it in GitHub Desktop.
Save fvilarino/da067aca6f079e720e07d9f2a76b2315 to your computer and use it in GitHub Desktop.
Single Line Composable
val colors = listOf(
Color.Red,
Color.Green,
Color.Blue,
Color.Cyan,
Color.Magenta,
)
@Composable
fun SingleLine(
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Layout(
modifier = modifier,
content = content,
) { measurables, constraints ->
var accumulatedWidth = 0
var numItems = 0
for (i in 0..measurables.lastIndex) {
val itemWidth = measurables[i].maxIntrinsicWidth(height = constraints.maxHeight)
if (accumulatedWidth + itemWidth > constraints.maxWidth) break
++numItems
accumulatedWidth += itemWidth
}
if (numItems == 0) {
layout(0, 0) {}
} else {
val looseConstraints = constraints.copy(
minWidth = 0,
minHeight = 0,
)
val placeables = measurables
.take(numItems)
.map { measurable -> measurable.measure(looseConstraints) }
val itemsWidth = placeables.fastSumBy { placeable -> placeable.width }
val maxHeight = placeables.maxBy { placeable -> placeable.height }.height
val remainder = constraints.maxWidth - itemsWidth
val spacer = remainder / (numItems + 1)
layout(
width = constraints.maxWidth,
height = maxHeight,
) {
var offsetX = spacer
placeables.forEach { placeable ->
placeable.placeRelative(
x = offsetX,
y = (maxHeight - placeable.height) / 2
)
offsetX += spacer + placeable.width
}
}
}
}
}
@Composable
fun Item(
index: Int,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.background(
color = colors[index % colors.size]
),
contentAlignment = Alignment.Center,
) {
Text(text = "Item $index")
}
}
@Preview(widthDp = 420)
@Composable
fun PreviewSingleLine() {
AppTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
SingleLine(
modifier = Modifier.fillMaxWidth()
) {
Item(
index = 0,
modifier = Modifier.size(80.dp)
)
Item(
index = 1,
modifier = Modifier.size(120.dp)
)
Item(
index = 2,
modifier = Modifier.size(160.dp)
)
Item(
index = 3,
modifier = Modifier.size(120.dp)
)
}
SingleLine(
modifier = Modifier.fillMaxWidth()
) {
Item(
index = 0,
modifier = Modifier.size(64.dp)
)
Item(
index = 1,
modifier = Modifier.size(80.dp)
)
Item(
index = 2,
modifier = Modifier.size(120.dp)
)
Item(
index = 3,
modifier = Modifier.size(80.dp)
)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment