Seems some device can report ```WindowInsets.navig...
# compose
t
Seems some device can report
Copy code
WindowInsets.navigationBars.asPaddingValues()
With values like 20.933334 dp, that will generate rounding errors later. It does not seems that there's any round/ceil helper for dp and we need to get the value then round then wrap to dp again? No better way?
a
I’m curious if you have an example of the rounding errors you’re running into if you use the value directly It’s expected that an integer number of pixels may not correspond to an integer number of
dp
because of different densities
t
This is a complex layout where I handle many things manually so lot's of dp additions. But see
there's a small line between the progress bar and the nav bar.
Still have not tried to repro by faking the value as I also fight some issue with Android 14 last beta that report wrong statusbar insets ignoring the cuttout 😞
a
Individual components will be rounded to a size of an integer number of pixels, so that might lead to accumulation of rounding depending on your logic. As an example,
Copy code
Column {
    Spacer(Modifier.height(10.dp))
    Spacer(Modifier.height(10.dp))
    Spacer(Modifier.height(10.dp))
}
and
Copy code
Column {
    Spacer(Modifier.height(30.dp))
}
might not result in the same height depending on the density
t
In that case the dp values are added so like 64.dp + 60.dp + that value for the peek height and that value for padding on a 60.dp item. Everything works nicely for 99% of the devices. Just for a few with those float dp for gesture it triggers this.
Without rounding what would be the proper way to handle this
a
I would do the addition in terms of pixels, once you’ve determined the size of subcomponents. https://medium.com/androiddevelopers/density-devices-and-flaky-tests-ce41ac1e6299 goes into more detail for how rounding can go awry on different devices. Even for integer dps, you can have rounding issues depending on the density, since density itself may not be an integer
t
But I still need to pass dp to nearly everything after that will bring back the rounding error.
And there will always be different component as the value is passed around as paddingvalue.
c
Hm. I dont want to trivialize the difficulty of this and i dont have all of the context. but i feel like ive built something very similar to this, in an edge to edge app and i never had an issue like this? is the issue bcause that bottom bar (with the play button, not the nav bar) animates?
t
Everything animates ;) the navbar collapse the small bar expand to real full edge to edge. and this support landscape or other case where there's no nav bar but a side bar.
And of course it's done efficiently to avoid recomposition during all the animations.
a
I think I’d need to see more specific code to know what’s going on, it definitely should be possible to do this nicely across densities and devices
t
The code is quite specific as everything is split in independent things that are tied via state for the animations. But given an edge to edge big box. To simplify you have the 1 first layer that is the content. The second layer that is kinda modal bottomsheet and a third layer that is the nav bar (optional in landscape for example). Since it's full edge to edge the nav bar is a fixed size with a bottom padding of the system nav bar. The modal player bottom sheet, when something is playing have a peek height set to system nav bar + navbar + it's own size. This is done like that for performance reasons during animations as when the compact player expand the nav bar move outside.
a
At what layer and in what units is the peek height being set?
t
Everything is done in dp. From what you told for the nav bar size since it's size + padding the rounding there will be the root cause.
The padding for system nav bar is always done as always present. But the nav bat is optional.
For now I've added a 2dp line of the proper color below the compact player. This work and is only visible during the animation to expand so not perfect but not so much ugly.
a
This is just a guess, but it’s possible that these two values are different: • the peek height (defined as a sum of other dp values) converted to pixels using density, and rounded to a whole number of pixels to place something • the individual resulting sizes of the nav bar, the player, and other components, summed together. Each component will separately round to a whole number of pixels for sizing, so there can be multiple places where rounding happens
t
Yes that's what you explained earlier and in the article. Unfortunately there will always be an addition. Even if I refactor and include the system nav bar padding in the nav bar size that I pass down to the player sheet (not using padding and passing the px value) The peek size will always be that value + the compact player height. I don't really see a solution.