https://kotlinlang.org logo
#compose
Title
# compose
j

Joseph Hawkes-Cates

02/08/2022, 5:58 PM
I’m seeing a weird issue that I’m thinking might be a bug. I have some logic to determine the Window Size Class that I took from one of the Android Developer Channel YouTube videos. I’m seeing that the first couple times I change the orientation of my device it seems to not be updating
LocalConfiguraiton.current
. If I remove the “orientation” entry from the “android:config” changes field in my manifest, then it works every time, but with that in there, it will not update the first couple times, then it’ll work after that. Code in 🧵
For reference I have this function that I took from the YouTube video on handling different screen sizes:
Copy code
@Composable
fun Activity.rememberWindowSizeClass(): WindowSize {
    val configuration = LocalConfiguration.current
    val windowMetrics = remember(configuration) {
        Timber.i("Recalculating window metrics")
        WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
    }
    val windowDpSize = with(LocalDensity.current) {
        windowMetrics.bounds.toComposeRect().size.toDpSize()
    }
    Timber.i("Screen size: w=${windowDpSize.width},h=${windowDpSize.height}")
    return when {
        windowDpSize.width < 600.dp -> WindowSize.SMALL
        windowDpSize.width < 840.dp -> WindowSize.MEDIUM
        else -> WindowSize.LARGE
    }
}
My expectation is that the call to LocalConfiguration.current should result in a recomposition upon orientation change and the remember block would have a new key so it would recalculate the metrics.
When I test, the first 2 orientation changes do not recalculate the WindowMetrics and so the logic still uses the measurements from before the device was rotated. After that it seems to recalculate upon orientation change as expected
As I said at the top of the thread if I remove orientation from the android:config list for my activity, then it works every time as I expect it to
r

Rick Regan

02/08/2022, 8:04 PM
I ran your code (using `println`s) and it worked for me (Pixel 4a in emulator, Compose 1.2.0-alpha02, androidx.window:1.0.0, AS Chipmunk Beta 1):
Copy code
@Composable
fun Activity.SlackOrientation() {
    val configuration = LocalConfiguration.current
    val windowMetrics = remember(configuration) {
        println("Recalculating window metrics")
        WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
    }
    val windowDpSize = with(LocalDensity.current) {
        windowMetrics.bounds.toComposeRect().size.toDpSize()
    }
    println("Screen size: w=${windowDpSize.width},h=${windowDpSize.height}")
    when {
        windowDpSize.width < 600.dp -> println("SMALL")
        windowDpSize.width < 840.dp -> println("MEDIUM")
        else -> println("LARGE")
    }
}
Here are the messages:
Copy code
Startup
-------
Recalculating window metrics
Screen size: w=392.72726.dp,h=850.9091.dp
SMALL
Screen size: w=392.72726.dp,h=850.9091.dp
SMALL

Rotate
------
Recalculating window metrics
Screen size: w=850.9091.dp,h=392.72726.dp
LARGE

Rotate back
-----------
Recalculating window metrics
Screen size: w=392.72726.dp,h=850.9091.dp
SMALL
That's with
android:configChanges="colorMode|density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode">
With that line deleted, it also works, but rotate and rotate back each repeat the last two lines, like for startup.
j

Joseph Hawkes-Cates

02/08/2022, 8:56 PM
Huh, interesting. Thanks for trying it out! I ran it on a Nexus 9 emulator on Android 11 and my Pixel 6 phone on Android 12 and it wouldn’t redo the calculation the first 2 times on either. I’m on AS Bumblebee and compose 1.1.0-rc3, though so maybe the difference is one of those things
r

Rick Regan

02/08/2022, 8:59 PM
I should also mention my emulator was running Android 11.
j

Joseph Hawkes-Cates

02/08/2022, 9:55 PM
Yeah, I still see the issue on my Pixel 6 after trying out compose 1.2.0-alpha02
I’m also seeing images not update when switching from dark mode to light mode
r

Rick Regan

02/09/2022, 1:02 PM
I see the same as you using the "Resizable API 32" emulator (there is no Pixel 6 emulator?). With the line in the manifest these are the messages:
Copy code
Startup
-------
Recalculating window metrics
Screen size: w=411.42856.dp,h=891.4286.dp
SMALL
Screen size: w=411.42856.dp,h=891.4286.dp
SMALL

Rotate
------
Screen size: w=411.42856.dp,h=891.4286.dp
SMALL

Rotate back
-----------
Recalculating window metrics
Screen size: w=411.42856.dp,h=891.4286.dp
SMALL

Rotate
------
Recalculating window metrics
Screen size: w=891.4286.dp,h=411.42856.dp
LARGE

Rotate back
-----------
Recalculating window metrics
Screen size: w=411.42856.dp,h=891.4286.dp
SMALL
(without the line in the manifest it works.) That would seem like a bug.
I also see that if you print
configuration.orientation
it will change appropriately on the first rotate (i.e., it will be '2' (landscape) even though you detect it as SMALL).
Also
BoxWithConstraints
works, "swapping"
maxWidth
and
maxHeight
on the first rotation.
19 Views