is there any reason why I shouldn't use `LocalConf...
# compose
c
is there any reason why I shouldn't use
LocalConfiguration.current.screenWidthDp
instead of something like the
WindowMetricsCalculator
as the
screenWidthDp
(and
screenHeightDp
) values seem to update with the size of the window (and on a foldable device, it also updates as expected)?
l
Different API levels will handle cutouts / multi window / picture in picture etc differently, so this is not a consistent view of the actual window size. If you care about the size of the window your app is displayed in, you should use
WindowMetricsCalculator
/
material3-window-size-class
https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes
Specifically even on the latest Android versions, I think
screenWidthDp
will always exclude insets, whereas
WindowMetricsCalculator
will include that, for the total size of the window
a
Exactly that,
screenWidthDp
and
screenHeightDp
can be smaller than the overall size of the
Window
with a difference that depends on the insets.
WindowMetricsCalculator
gives a more accurate value. If you rotate your device 90 degrees, you'd expect that the "width" and "height" values swap. That is true for
WindowMetricsCalculator
, but won't necessarily be true for
screenWidthDp
and
screenHeightDp
Another fun edge case fact related to this: it's possible to have
LocalConfiguration.current.orientation
return
portrait
, but
screenWidthDp
is actually larger than
screenHeightDp
in a situation where the aspect ratio is almost square (although that's more of another reason to avoid depending on
portrait
vs
landscape
to make large layout decisions)
c
Thank you for this! This is the kind of insight I can't find on my own, much appreciated!
Just checking then, is the use of
LocalConfiguration.current
here to somehow observe configuration changes as a side effect so the function will recompose?
Copy code
@ExperimentalMaterial3WindowSizeClassApi
@Composable
fun calculateWindowSizeClass(activity: Activity): WindowSizeClass {
    // Observe view configuration changes and recalculate the size class on each change. We can't
    // use Activity#onConfigurationChanged as this will sometimes fail to be called on different
    // API levels, hence why this function needs to be @Composable so we can observe the
    // ComposeView's configuration changes.
    LocalConfiguration.current
    val density = LocalDensity.current
    val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
    val size = with(density) { metrics.bounds.toComposeRect().size.toDpSize() }
    return WindowSizeClass.calculateFromSize(size)
}
l
Yes