Search code examples
androidkotlinandroid-jetpack-composeandroid-softkeyboardcompose-recomposition

Observing Soft Keyboard Visibility, Opened/Closed Jetpack Compose


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.


Solution

  • 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