Equal size tiles
Author: Francesc Vilariño Güell
Custom layout to constraint and place children in slots of equal dimensions using a single measure pass
@Composable | |
fun EqualSizeTiles( | |
modifier: Modifier = Modifier, | |
content: @Composable () -> Unit, | |
) { | |
Layout( | |
content = content, | |
modifier = modifier, | |
) { measurables, constraints -> | |
layoutTiles( | |
measurables, | |
constraints | |
) | |
} | |
} | |
private fun MeasureScope.layoutTiles( | |
measurables: List<Measurable>, | |
constraints: Constraints, | |
): MeasureResult { | |
val tileHeight = constraints.maxHeight | |
val tileWidths = measurables.map { measurable -> | |
measurable.maxIntrinsicWidth(tileHeight) | |
} | |
val tileWidth = tileWidths.maxOrNull() ?: 0 | |
val tileConstraints = Constraints( | |
minWidth = tileWidth, | |
minHeight = 0, | |
maxWidth = tileWidth, | |
maxHeight = constraints.maxHeight, | |
) | |
val placeables = measurables.map { measurable -> | |
measurable.measure(tileConstraints) | |
} | |
val width = (placeables.size * tileWidth).coerceAtMost(constraints.maxWidth) | |
return layout(width = width, height = tileHeight) { | |
placeables.forEachIndexed { index, placeable -> | |
placeable.place(tileWidth * index, 0) | |
} | |
} | |
} | |
@Preview(showBackground = true) | |
@Composable | |
private fun EqualSizeTilesPreview() { | |
WeatherSampleTheme { | |
Surface(modifier = Modifier | |
.width(512.dp) | |
.background(color = Color.Yellow)) { | |
EqualSizeTiles( | |
modifier = Modifier | |
.height(64.dp) | |
.background(color = Color.Green) | |
.padding(all = 8.dp) | |
) { | |
Text( | |
text = "Left", | |
textAlign = TextAlign.Center, | |
modifier = Modifier | |
.background(color = Color.Red) | |
.padding(all = 8.dp) | |
.fillMaxHeight(), | |
) | |
Text( | |
text = "Center", | |
textAlign = TextAlign.Center, | |
modifier = Modifier | |
.background(color = Color.Yellow) | |
.padding(all = 8.dp) | |
.fillMaxHeight(), | |
) | |
Text( | |
text = "Right element", | |
textAlign = TextAlign.Center, | |
modifier = Modifier | |
.background(color = Color.Blue) | |
.padding(all = 8.dp) | |
.fillMaxHeight(), | |
) | |
} | |
} | |
} | |
} |
Have a project you'd like to submit? Fill this form, will ya!
If you like this snippet, you might also like:
Maker OS is an all-in-one productivity system for developers
I built Maker OS to track, manage & organize my life. Now you can do it too!