https://kotlinlang.org logo
Title
c

czuckie

02/20/2023, 3:29 PM
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

Louis Pullen-Freilich [G]

02/20/2023, 4:07 PM
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

Alex Vanyo

02/20/2023, 8:01 PM
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

czuckie

02/21/2023, 9:16 AM
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?
@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

Louis Pullen-Freilich [G]

02/21/2023, 11:24 AM
Yes