I have a column with it's height set to maxSize. A...
# compose
c
I have a column with it's height set to maxSize. And I have 4 text composables in that column. I want to be able to say that the 2nd Text "if there is no room for all 4 texts on the screen, please hide this one text" How would I do that in compose? Essentially I feel like I want to create a
Modifier.onlyShowIfTheresEnoughSpace
s
Sounds quite specific, maybe a custom layout would be the solution here? Recently there was this snippet posted here https://kotlinlang.slack.com/archives/CJLTWPH7S/p1668131336344949?thread_ts=1668110653.982419&cid=CJLTWPH7S, not nearly what you are looking for, but definitely something that you can draw inspiration from to see what’s available. Basically take the intrinsic max height of everything, and if that exceeds the available height, simply never measure and never place the 2nd item. Just an idea 🤷‍♂️
f
Just and idea. Not sure if it'll work. Use
weight()
modifier so the item is "measured last" and then use
layout()
modifier on the item and figure out if you have enough space to place it.
k
It also depends and what do you define as "not enough room for all 4 texts" this sounds a lot like UI based on the size of the display, like when you do mobile vs tablet UI, you would probably need to define a stop height value in which your composable should not be part of the layout, there's no perfect solution
f
I would suggest to use a layout with intrinsic measurements, to determine if you have snough space
Copy code
@Composable
fun Tiles(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    Layout(
        modifier = modifier,
        content = content,
    ) { measurables, constraints ->
        require(measurables.size == 4) { "No bueno" }
        val heights = measurables
            .map { measurable -> measurable.maxIntrinsicHeight(constraints.maxWidth) }
        val requiredHeight = heights.sum()
        val measurablesToPlace = if (requiredHeight <= constraints.maxHeight) {
            measurables
        } else {
            measurables.dropLast(1)
        }
        val looseConstraints = constraints.copy(minHeight = 0)
        val placeables = measurablesToPlace.map { measurable -> measurable.measure(looseConstraints) }
        layout(
            width = constraints.maxWidth,
            height = placeables.sumOf { it.height },
        ) {
            var y = 0
            placeables.forEach { placeable ->
                placeable.placeRelative(
                    x = 0,
                    y = y,
                )
                y += placeable.height
            }
        }
    }
}

@Preview(widthDp = 360)
@Composable
fun PreviewTiles() {
    PlaygroundTheme {
        Surface(
            color = MaterialTheme.colorScheme.background
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(all = 16.dp),
            ) {
                Tiles(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(96.dp)
                ) {
                    Text(
                        text = "Foo",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Red.copy(alpha = .3f))
                    )
                    Text(
                        text = "Bar",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Blue.copy(alpha = .3f))
                    )
                    Text(
                        text = "Baz",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Red.copy(alpha = .3f))
                    )
                    Text(
                        text = "FooBarBaz",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Blue.copy(alpha = .3f))
                    )
                }

                Tiles(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(top = 16.dp)
                        .height(40.dp)
                ) {
                    Text(
                        text = "Foo",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Red.copy(alpha = .3f))
                    )
                    Text(
                        text = "Bar",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Blue.copy(alpha = .3f))
                    )
                    Text(
                        text = "Baz",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Red.copy(alpha = .3f))
                    )
                    Text(
                        text = "FooBarBaz",
                        textAlign = TextAlign.Center,
                        modifier = Modifier.background(Color.Blue.copy(alpha = .3f))
                    )
                }
            }
        }
    }
}
this works on 4 composables and assumes the last one is the one to drop, it's basic but you can build on it
c
Thanks everyone. this definitely gets me some ideas.