JayDee
JayDee

Reputation: 93

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.

Upvotes: 6

Views: 2441

Answers (1)

z.g.y
z.g.y

Reputation: 6277

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

Upvotes: 7

Related Questions