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

K Merle

08/18/2022, 10:16 AM
How to detect when soft-keyboard opened/closed?
s

Stylianos Gakis

08/18/2022, 11:18 AM
What do you need this information for? Depending on the reason you may get different answers.
k

K Merle

08/18/2022, 11:24 AM
I wanna hide/show
submit
button when keyboard is opened/closed.
Main reason for this is that sometimes
submit
button changes a for cause of the
windowSoftInputMode
adjustResize
value that we have.
s

Stylianos Gakis

08/18/2022, 11:29 AM
Didn’t quite get the second message, but for the first one, could you give
WindowInsets.isImeVisible
a try? It’s part of the new compose 1.2 inset APIs.
k

K Merle

08/18/2022, 11:30 AM
Yea, tried it, but they seem to not provide a
State
, but just a
Boolean
value. So I should still have sort of callback to react to keyboard state change.
s

Stylianos Gakis

08/18/2022, 11:34 AM
WindowInsets.isImeVisible
is a composable function, aka you’ll always be getting the latest value. It’s kind of like
State<Boolean>
, but you don’t see it, you see just a
Boolean
, and get the observability for free since you’re inside a composable function.
I’m curious to see how you’re calling that function and why it doesn’t work for you. It’s possibly me who’s misunderstanding something.
k

K Merle

08/18/2022, 11:36 AM
I see. I was trying to debug it before and was getting that initial
false
value only. Having
WindowInsets.isImeVisible
inside the composable function and opening and closing the keyboard should be enough to recompose that
isImeVisible
and return true when I open keyboard?
s

Stylianos Gakis

08/18/2022, 11:42 AM
Yeah that should be the case indeed
k

K Merle

08/18/2022, 11:43 AM
Maybe I did something wrong, I'll check that out again, tnx.
s

Stylianos Gakis

08/18/2022, 12:24 PM
It’s here in the getter
Copy code
@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
    @ExperimentalLayoutApi
    @Composable
    @NonRestartaleComposable
    get() = WindowInsetsHolder.current().ime.isVisible
the getter is a composable function, aka you get this observability. Take a look at this post from @Zach Klippenstein (he/him) [MOD] at the section
Snapshot state: Observation
Copy code
Composable functions already have this implicit observation logic wired up, which is why code like this would just work:

@Composable fun CounterButton(counter: Counter) {
  Text("${counter.label}: ${counter.value}")
}

The Compose compiler wraps the body of this CounterButton function with code that effectively observes any and all MutableStates that happen to be read inside the function.
And
isVisible
is in fact a
State
object as seen here, so it works. That’s my understanding of all this at least, I hope I’m not giving you any wrong information here 😊
a

Alejandro Rios

08/18/2022, 12:47 PM
I was looking the same yesterday and I've found this
k

K Merle

08/18/2022, 12:51 PM
@Alejandro Rios Tried that example today. This example has a slight delay with a callback, and for my use case I had an issue. Button that I need to hide when keyboard opens is at the bottom-end of a screen. Opening a keyboard animates a button for a small amount of time before button disappears.
a

Alex Vanyo

08/18/2022, 5:09 PM
Yes, @Stylianos Gakis is right,
WindowInsets.isImeVisible
is snapshot state backed, so it will automatically update when the keyboard is opening and closing. Are you using
WindowCompat.setDecorFitsSytemWindows(window, false)
and
adjustResize
? (I think you mentioned
adjustResize
)
k

K Merle

08/18/2022, 5:48 PM
@Alex Vanyo Yes, I'm using
WindowCompat.setDecorFitsSytemWindows(window, false)
, but dynamically change boolean value, depending on a navigation `route`where I'm at, and I do use
adjustResize
Alright, in this particular case it was set to
true
, and I wasn't getting the keyboard state. Setting it to
false
gives me value re-actively as @Stylianos Gakis suggested.
a

Alex Vanyo

08/18/2022, 6:16 PM
Yeah, that’s unfortunate but makes sense. If the app doesn’t get as much information about it can about the insets it may not be able to know as accurately if the keyboard is open or not
k

K Merle

08/18/2022, 6:18 PM
Thanks for clarification Alex.
a

Alex Vanyo

08/18/2022, 6:30 PM
Your best bet will probably be to do
WindowCompat.setDecorFitsSytemWindows(window, false)
on that screen (handling the insets there yourself) and then getting the accurate value for
WindowInsets.isImeVisible
k

K Merle

08/18/2022, 6:31 PM
Was thinking of that, will try that tomorrow. Tnx
1178 Views