3

I'm using Scaffold for my main screen with a fixed bottomBar that is visible in every screen of the app, and I'm applying the innerPadding of the Scaffold to its content.

I want the keyboard to appear over the bottomBar, and for that I'm applying the imePadding() only to the Scaffold's content.

However, when the keyboard is opened, both the Scaffold's innerPading and imePadding() are applied to the contents padding.

I've tried to go through the Accompanist Insets migration, but no lucky.

Is there anyway that I can prevent it and apply only one or the other?

Here is a piece of my code:

Scaffold(
    topBar = { },
    bottomBar = { },
    modifier = Modifier
        .systemBarsPadding()
) { innerPadding ->
    Content(
        modifier = Modifier
            .padding(innerPadding)
            .imePadding()
    )
}

And this is the result:

enter image description here

With the now, deprecated, Accompanist Insets, I was using the following solution:

val isImeVisible = LocalWindowInsets.current.ime.isVisible
val contentPadding = remember(isImeVisible) {
    if (isImeVisible) PaddingValues(top = innerPadding.calculateTopPadding()) else innerPadding
}
rewgoes
  • 536
  • 2
  • 6
  • 19

1 Answers1

3

According to Accompanist Insets migration, LocalWindowInsets.current.ime should be replaced with WindowInsets.ime.

It doesn't have isVisible for now, until this bug is fixed. Here's how I've re-created it for now:

val WindowInsets.Companion.isImeVisible: Boolean
    @Composable
    get() {
        val density = LocalDensity.current
        val ime = this.ime
        return remember {
            derivedStateOf {
                ime.getBottom(density) > 0
            }
        }.value
    }

Usage:

val isImeVisible = WindowInsets.isImeVisible

This should work with your old remember(isImeVisible) code.

Pylyp Dukhov
  • 38,521
  • 10
  • 57
  • 92
  • Can we listen to the keyboard open/close state changes using this approach? – SpiralDev Apr 12 '22 at 10:13
  • @SpiralDev in compose instead of listening for changes we're reacting on state changes, which trigger recomposition of the view which is using this particular state. E.g. you can write `if (WindowInsets.isImeVisible) Text("visible") else Text("hidden")`, if you need to launch some action, you can do this with `LaunchedEffect`: `if (WindowInsets.isImeVisible) LaunchedEffect(Unit) { doSomeStuff }`. – Pylyp Dukhov Apr 12 '22 at 10:46
  • How about [this](https://stackoverflow.com/a/69533584/5985958) then, It detects state changes? – SpiralDev Apr 12 '22 at 11:01
  • @SpiralDev I'm not saying that you can't, sometimes you have to, like in the linked case, when you need to deal with old Android API. – Pylyp Dukhov Apr 12 '22 at 11:37