I'm trying to actively observe the soft keyboard visibility, currently, I'm trying to observe it with
WindowInsets.isImeVisible
but I can't seem to observe its state change. Someone mentioned using
ViewCompat.setOnApplyWindowInsetsListener()
but I can't quite understand how to implement this to observe the keyboard visibility.
I have managed to use
WindowInsets.isImeVisible
however, it only applies at the time I navigate to the page and the keyboard auto opens.
Taken from this S.O post,
You can use this to check if the keyboard
is opened or closed
internal enum class Keyboard {
Opened, Closed
}
@Composable
internal fun keyboardAsState(): State<Keyboard> {
val keyboardState = remember { mutableStateOf(Keyboard.Closed) }
val view = LocalView.current
DisposableEffect(view) {
val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
val rect = Rect()
view.getWindowVisibleDisplayFrame(rect)
val screenHeight = view.rootView.height
val keypadHeight = screenHeight - rect.bottom
keyboardState.value = if (keypadHeight > screenHeight * 0.15) {
Keyboard.Opened
} else {
Keyboard.Closed
}
}
view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
onDispose {
view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
}
}
return keyboardState
}
You can test it like this,
@Composable
fun KeyboardCheck() {
val keyboard by keyboardAsState()
Log.e("KeyboardCheck", "$keyboard")
TextField(value = "", onValueChange = {})
}
and every time the keyboard opens and closes it will print
E/KeyboardCheck: Closed
E/KeyboardCheck: Opened
E/KeyboardCheck: Closed
E/KeyboardCheck: Opened
E/KeyboardCheck: Closed