I've tried peeking at the internals of the layout ...
# compose
o
I've tried peeking at the internals of the layout system but can't figure out where the rule is and how to override it.
a
Write a layout modifier that measures and positions the child according to your desired policy but that reports its own size as being within the requested constraints
Then apply that modifier to elements where you would like to override the default behavior
k
A simple version could be like this:
Copy code
data class BiggerContentStartAlignment(
    private val childSize: Dp
) : LayoutModifier {
    override fun MeasureScope.measure(
        measurable: Measurable,
        constraints: Constraints,
        layoutDirection: LayoutDirection
    ): MeasureScope.MeasureResult {
        val wrappedConstraints = constraints.copy(minWidth = 0.ipx)
        val placeable = measurable.measure(wrappedConstraints)
        val wrapperWidth = max(constraints.minWidth, placeable.width)
        val wrapperHeight = max(constraints.minHeight, placeable.height)
        return layout(
            wrapperWidth,
            wrapperHeight
        ) {
            placeable.placeAbsolute((childSize.toIntPx() - wrapperWidth) / 2, 0.ipx)
        }
    }
}
Copy code
Box(
    modifier = Modifier.width(100.dp).height(100.dp)
        .drawBackground(Color.Yellow)
        .plus(BiggerContentStartAlignment(500.dp))

) {
    Box(
        modifier = Modifier
            .width(500.dp).preferredHeight(40.dp)
            .drawBorder(10.dp, Color.Blue)
    ) {
    }
}
o
Thanks a lot ! I'll try that out
k
you're welcome, with your question I had a chance to play around with
LayoutModifier
, If possible please share your final code I'd like to learn more about this parts of compose.
@Octave Decaux based on https://kotlinlang.slack.com/archives/CJLTWPH7S/p1592162501227200 my assumption about
LayoutModifier
was wrong the code above is not correct. It positions the outerBox but we should position the inner box. It seemed to be correct because I put the
drawBackgroundColor
before
.plus(BiggerContentStartAlignment(500.dp))
I wrote another one, this one seems to be correct, but still it might need more work to be more general.
Copy code
fun Modifier.alignLeftWidth(width: Dp) = AlignLeft(width) + sizeIn(minWidth = width, maxWidth = width)
data class AlignLeft(
    val width:Dp
) : LayoutModifier {
    override fun MeasureScope.measure(
        measurable: Measurable,
        constraints: Constraints,
        layoutDirection: LayoutDirection
    ): MeasureScope.MeasureResult {
        val placeable = measurable.measure(constraints)
        return layout( placeable.width, placeable.height ) {
            placeable.place((width.toIntPx() - placeable.width) / 2f , 0.ipx)
        }
    }
}
Copy code
Box(modifier = Modifier.fillMaxSize()) {
    Box(
        modifier = Modifier.width(100.dp).height(100.dp)
            .drawBackground(Color.Yellow)
    ) {
        Box(
            modifier = Modifier
                .alignLeftWidth(500.dp)
                .preferredHeight(40.dp)
                .drawBorder(10.dp, Color.Blue)
        ) {
            Text("Hello")
        }
    }
}
alignLeftWidth
sets the width and also aligns to left.