Hi all. I am looking to make `FlowRow` with 2 equa...
# compose
r
Hi all. I am looking to make
FlowRow
with 2 equal size columns. For the child items of the row I tried to set the widths as
fillMaxWidth(0.5f)
on some preview sizes it will make it single column. If i update it to be
fillMaxWidth(0.4999999f)
it will always be two rows with any screen size. I am just really interested on why for some screen configurations the 0.5 works but not on all. Any insight or thoughts would be appreciated. Know there are other ways just really intrigued why that does not seem to work.
Copy code
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun FlowRowRounding(maxWidth: Float) {
    FlowRow(
        modifier = Modifier.fillMaxWidth(),
        maxItemsInEachRow = 2,
    ) {
        for (i in 1..2) {
            Text(
                modifier = Modifier.fillMaxWidth(maxWidth),
                text = "Item $i",
                textAlign = TextAlign.Center,
            )
        }
    }
}

@Preview(widthDp = 350, showBackground = true)
@Composable
fun FlowRowMaxWidthHalf() {
    FlowRowRounding(maxWidth = .5f)
}

@Preview(widthDp = 350, showBackground = true)
@Composable
fun FlowRowMaxWidth49999() {
    FlowRowRounding(maxWidth = .4999999f)
}
Snippet showing the issue.
a
Layout is performed in integer pixels, so rounding must occur depending on the exact amount of space available, and rounding can accumulate. For the wrapping case with a weight of
0.5
, I’m guessing that there are an odd number of pixels available. The pre-rounded solution would be to have each item take up
0.5
of a pixel, but that isn’t possible, so both round up - which then takes 1 more pixel than is available, so it wraps
r
Thanks for the answer! That is really interesting. Was digging into some of that and that was my guess as well. Will see if I can log out some widths of those items and check the difference.
a
https://medium.com/androiddevelopers/density-devices-and-flaky-tests-ce41ac1e6299 goes a bit into the details here more with another example. The accumulation of errors from rounding can sometimes add up too. The max width of
0.49999f
is probably resulting in both sizes rounding down, but that means the sum of item1's width and item2's width can be one smaller than the total amount of available width. This probably doesn’t matter in most cases, but you could end up with some 1 pixel artifacts when backgrounds get involved
r
Thank you for sharing that! That is really fascinating. One of those things that day to day you dont think a ton about but pop up and are fun to think around. I am going to actually go update my previews to explicitly define the DPI, I am realizing I have no idea what the system is giving it by default (I assume it would match the Mac book I am developing on but not sure)
Anyway thank you much, that was fun thinking about today!
I guess the other are i need to dive into, if i do a
Row
with the same 2 items on the same preview device that are
0.5f
they render correctly. So likely something more going on there with regards to the math that goes into calculating maximum width of a
FlowRow
vs a
Row
a
Row
and
Column
do some very specific handling around those accumulated errors when weights are involved: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]icy.kt;l=222-224;drc=25969d8585b6735cf7b56bf4dc118c68d3a1704f
212 Views