What's the recommended way to align elements in ot...
# compose
m
What's the recommended way to align elements in other elements? Say I have the following where I want all of the first columns in each row to have the same width:
Copy code
+---------+--------+
| 20 ms   | ABCDEF |
+---------+--------+

+---------+-------------+
| 1200 ms | GHIJKLMNOPQ |
|         | RSTUV       |
+---------+-------------+
In traditional CSS I'd use a grid for this, but this isn't really a thing in Compose. I could add an onGloballyPositioned modifier to each element in each Row{} to determine their width and get the maximum and then apply that to all, but I feel like there should be an easier way to do something this common, but I haven't found a clean way to do it.
s
Not sure what you mean exactly here. Your graphic here does not exactly have equal widths on your two items. You say first that you want to align elements to other elements. And then that you want the columns to have equal widths. Do you want both to be true, or what? If you had some screenshots or if you could elaborate a bit more on your requirements it'd make it easier to solve this
m
Your graphic here does not exactly have equal widths on your two items.
Might be a font issue? On my screen, both elements on the left have the exact same width, matching the largest size required to fit all elements.
here's a quick visual draft
s
So you want the entire column to be as wide as the first item in that column?
Or rather, as big as the biggest item in the column
m
the biggest item, yes
s
Is this a list of infinite items, do you need it to be lazy?
m
The list is finite
s
Yeah, rather, is it big enough to warrant being lazy?
m
I doubt I'll ever have more than 10 entries, and I don't think they need to be lazy since they're all loaded at the same time.
The easiest solution would be to implement this as two columns, but even then I'd need to align their heights brining us back to the same problem, not to mention some other issues with how each line is supposed to be collapsible to show more details
s
As a side not, if you needed it to be lazy, you could look into these two https://github.com/oleksandrbalan/minabox https://github.com/oleksandrbalan/lazytable In fact you could still do that, but let's see what else we can do before this
Is it always 2 columns? And is it always on that first "column" contains text only?
m
Yes, at least for now the layout is designed to be consistent
I'm looking at LazyTable, but it seems to still require hardcoded column sizes. (https://github.com/oleksandrbalan/lazytable/blob/main/demo/src/commonMain/kotlin/eu/wewox/lazytable/screens/LazyTablePinnedScreen.kt#L112-L128) Is there no way around this?
s
You can use
rememberTextMeasurer
, try to measure all the texts that will go to your first column. And take the max width from all of them. Then assign a fixed width to all the items in that first column. And the right item can get a weight(1f) I suppose to fill the rest
Copy code
val texts List<String>...
val textStyle = tableStyle.textStyle
val textMeasurer = rememberTextMeasurer(cacheSize = texts.size)
val fixedWidth = texts.maxOf { text ->
  textMeasurer.measure(
    text = text,
    style = textStyle,
    softWrap = false,
    maxLines = 1,
  ).size.width
}
Row {
  Box(Modifier.width(fixedWidth)) { // left content here }
  Box(Modifier.weight(1f, true) { // right content here }
}
We do something very similar right here https://github.com/HedvigInsurance/android/blob/b8ee06bd38020c95fb4e5d1fa49ec46663[…]dvig/android/shared/tier/comparison/ui/ComparisonDestination.kt In a layout that looks something like this. You probably don't have the same requirements as we do, but it can serve as a point of reference on how to use the text measurement + a custom Layout perhaps.