Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Android Keyboard Status Observable
* Manages access to the Android soft keyboard.
class KeyboardManager @Inject constructor(private val activity: Activity) {
* Observable of the status of the keyboard. Subscribing to this creates a
* Global Layout Listener which is automatically removed when this
* observable is disposed.
fun status() = Observable.create<KeyboardStatus> { emitter ->
val rootView = activity.findViewById<View>(
// why are we using a global layout listener? Surely Android
// has callback for when the keyboard is open or closed? Surely
// Android at least lets you query the status of the keyboard?
// Nope!
val globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
val rect = Rect().apply { rootView.getWindowVisibleDisplayFrame(this) }
val screenHeight = rootView.height
// rect.bottom is the position above soft keypad or device button.
// if keypad is shown, the rect.bottom is smaller than that before.
val keypadHeight = screenHeight - rect.bottom
// 0.15 ratio is perhaps enough to determine keypad height.
if (keypadHeight > screenHeight * 0.15) {
} else {
emitter.setCancellable {
enum class KeyboardStatus {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.