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.
CodePudding user response:
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