https://kotlinlang.org logo
#compose-android
Title
# compose-android
t

Timo Drick

12/13/2023, 10:59 AM
I would like to fake WindowInsets in the compose preview. To be able to simulate edge-to-edge configurations with different orientations and navigation bar (Button/Gesture navigation). Unfortunately the WindowInsetsHolder which is used for this is a internal class. Do anyone have some ideas how to do this?
s

Stylianos Gakis

12/13/2023, 12:27 PM
You can use some constructor they got there to pass in your own value for w/h. And it should just work. Look around the apis a bit, something exists for sure
t

Timo Drick

12/13/2023, 12:29 PM
I tried to use the view api:
Copy code
val insets = Insets.of(50, 100, 50, 150)
    val test = WindowInsets.Builder()
        .setInsets(WindowInsets.Type.systemBars(), insets)
        .setVisible(WindowInsets.Type.systemBars(), true)
        .build()
    view.dispatchApplyWindowInsets(test)
But this does not work in the Preview
There are only modifiers to consume insets. You can not set them. And all is internal. Did not found a way to set insets in the preview yet
Unfortunately for the window instets they did not used this CompositionLocal approach where it is easy to provide an own implementation
s

Stylianos Gakis

12/13/2023, 1:02 PM
For some reason I somehow understood that since you want to test different sizes, orientations etc that you want to fake WindowSizeClass instead of insets, that’s my bad 🙈
t

Timo Drick

12/13/2023, 1:05 PM
It looks like there is a normal activity used for the previews in android studio (PreviewActivity) but in my tests the view.dispatchApplyWindowInsets did not had any effect on the compose insets.
s

Stylianos Gakis

12/13/2023, 2:11 PM
Does it apply when you actually run the preview in your device, as opposed to how it runs on AS?
t

Timo Drick

12/13/2023, 2:12 PM
No i was also not able to override the device window insets. Just working on this.
So not sure if it is possible
LocalView.current.rootView.updatePadding is working in preview
I created a issue for this here: https://issuetracker.google.com/issues/316195049
So finally i think i found a good solution hacking into the internal classes of Compose. Of course this will break if they change anything:
Copy code
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")

package test.package

import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding

@Composable
fun injectInsets() {
    val insetsHolder = WindowInsetsHolder.current()
    LaunchedEffect(Unit) {
        if (Build.VERSION.SDK_INT >= 30) {
            val testInsets = Insets.of(50, 200, 50, 250)
            val test = android.view.WindowInsets.Builder()
                .setInsets(android.view.WindowInsets.Type.statusBars(), testInsets)
                .setVisible(android.view.WindowInsets.Type.systemBars(), true)
                .build()
            val compat = WindowInsetsCompat.toWindowInsetsCompat(test)
            insetsHolder.update(compat, 0)
        }
    }
}