Ben Abramovitch
06/30/2021, 10:59 PMTash
06/30/2021, 11:23 PMBen Abramovitch
06/30/2021, 11:24 PMTash
06/30/2021, 11:25 PMBen Abramovitch
06/30/2021, 11:25 PMTash
06/30/2021, 11:59 PMwidth = totalWidth
in your layout, (0,0) is actually offscreen, and what you need is almost a translation of the “canvas” to bring 0,0 to the top-left of the visible windowAlignmentLine
, how’d that go?Ben Abramovitch
07/01/2021, 12:04 AMpackage androidx.compose.ui.layout
fun layout(
width: Int,
height: Int,
alignmentLines: Map<AlignmentLine, Int> = emptyMap(),
placementBlock: Placeable.PlacementScope.() -> Unit
) = object : MeasureResult {
override val width = width
override val height = height
override val alignmentLines = alignmentLines
override fun placeChildren() {
Placeable.PlacementScope.executeWithRtlMirroringValues(
width,
layoutDirection,
placementBlock
)
}
}
}
Adam Powell
07/01/2021, 12:44 AMBen Abramovitch
07/01/2021, 12:45 AMAdam Powell
07/01/2021, 12:45 AMconstraints.maxWidth
in that codeBen Abramovitch
07/01/2021, 12:51 AMconstraints.copy(
minWidth = headerWidth,
maxWidth = headerWidth,
minHeight = height,
maxHeight = height,
)
Layout(
modifier = Modifier.fillMaxWidth(),
content = {
columnList.forEach { header ->
Box {
headerContent(header)
}
}
},
)
headerContent: @Composable (title: String) -> Unit = { title ->
Text(title, modifier = Modifier.fillMaxWidth())
},
Adam Powell
07/01/2021, 1:04 AMlayout(width = totalWidth, height = height) {
and those are calculated as
val height = 45.dp.roundToPx()
val totalWidth = headerWidth * numberOfHeaders
both of which completely ignore the incoming constraints
layout
must be in range of the constraints
, if you violate that, your measurable gets clamped to the constraints and your placement is centered in the clamped space where your parent placed youBen Abramovitch
07/01/2021, 1:05 AMAdam Powell
07/01/2021, 1:06 AM) { measureables, constraints ->
Ben Abramovitch
07/01/2021, 1:06 AMAdam Powell
07/01/2021, 1:06 AMBen Abramovitch
07/01/2021, 1:06 AMAdam Powell
07/01/2021, 1:07 AMBen Abramovitch
07/01/2021, 1:09 AMLayout(
modifier = Modifier.fillMaxWidth(headerWidth * numberOfHeaders.toFloat()).fillMaxHeight(100f),
content = {
columnList.forEach { header ->
Box {
headerContent(header)
}
}
}
)
This doesn’t work either (i changed height to also be 100 further below)@Composable
fun HeaderTest(
columnList: List<String>,
headerWidth: Dp,
headerContent: @Composable (title: String) -> Unit = { title ->
Text(title, modifier = Modifier.fillMaxWidth())
},
) {
val numberOfHeaders = columnList.count()
Layout(
modifier = Modifier
.width(headerWidth * numberOfHeaders)
.height(100.dp)
.fillMaxHeight()
.fillMaxWidth(),
content = {
columnList.forEach { header ->
Box {
headerContent(header)
}
}
}
) { measureables, constraints ->
val height = 100.dp
val totalWidth = headerWidth * numberOfHeaders
val placeWithHeader = measureables.map { measurable ->
val constraint = constraints.copy(
minWidth = headerWidth.roundToPx(),
maxWidth = headerWidth.roundToPx(),
minHeight = height.roundToPx(),
maxHeight = height.roundToPx()
)
measurable.measure(constraint)
}
layout(width = totalWidth.roundToPx(), height = height.roundToPx()) {
placeWithHeader.forEachIndexed { index, placeable ->
val offset = index * headerWidth.roundToPx()
placeable.place(offset, 0)
}
}
}
}
Adam Powell
07/01/2021, 1:18 AMval height = 100.dp.roundToPx().coerceIn(constraints.minHeight, constraints.maxHeight)
val totalWidth = (headerWidth * numberOfHeaders).coerceIn(constraints.minWidth, constraints.maxWidth)
Ben Abramovitch
07/01/2021, 1:33 AMLayout(
modifier = modifier,
content = content
) { measurables, constraints ->
// Don't constrain child views further, measure them with given constraints
// List of measured children
val placeables = measurables.map { measurable ->
// Measure each children
measurable.measure(constraints)
}
But it also does the layout different….
// Set the size of the layout as big as it can
layout(constraints.maxWidth, constraints.maxHeight) {
Lots more reading to do, but this is why i’m starting sooner!Adam Powell
07/01/2021, 1:37 AMLayout
composable influence but don't completely control the constraints your layout receivesmeasurable.measure(constraints)
, it's calling the same kind of measuring code you're writing right now, but on the child elementlayout(width, height) {
function in that block, you're telling it the desired size of the Placeable
that the measure call returnsBen Abramovitch
07/01/2021, 1:42 AMAdam Powell
07/01/2021, 1:43 AMBen Abramovitch
07/01/2021, 1:43 AM