Soft keyboard event listener

Detect when the keyboard is visible and when not.

Usage

Sample code:

activity?.let { isKeyboardVisible ->
        KeyboardEventListener(isKeyboardVisible) {
            if (it) {
                // visible. Do stuff here
            } else {
                // not visible. Do other stuff here
            }
        }
    }

The listener, as found here

class KeyboardEventListener(
        private val activity: FragmentActivity,
        private val callback: (isOpen: Boolean) -> Unit
) : LifecycleObserver {

    private val listener = object : ViewTreeObserver.OnGlobalLayoutListener {
        private var lastState: Boolean = activity.isKeyboardOpen()

        override fun onGlobalLayout() {
            val isOpen = activity.isKeyboardOpen()
            if (isOpen == lastState) {
                return
            } else {
                dispatchKeyboardEvent(isOpen)
                lastState = isOpen
            }
        }
    }

    init {
        // Dispatch the current state of the keyboard
        dispatchKeyboardEvent(activity.isKeyboardOpen())
        // Make the component lifecycle aware
        activity.lifecycle.addObserver(this)
        registerKeyboardListener()
    }

    private fun registerKeyboardListener() {
        activity.findViewById<View>(android.R.id.content).viewTreeObserver.addOnGlobalLayoutListener(listener)
    }

    private fun dispatchKeyboardEvent(isOpen: Boolean) {
        when {
            isOpen -> callback(true)
            !isOpen -> callback(false)
        }
    }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_PAUSE)
    @CallSuper
    fun onLifecyclePause() {
        unregisterKeyboardListener()
    }

    private fun unregisterKeyboardListener() {
        activity.findViewById<View>(android.R.id.content).viewTreeObserver.removeOnGlobalLayoutListener(listener)
    }
}