package com.reactnativenavigation.utils; import android.content.Context; import android.graphics.Rect; import android.view.View; import android.view.ViewTreeObserver; import android.view.inputmethod.InputMethodManager; import com.reactnativenavigation.NavigationApplication; public class KeyboardVisibilityDetector { // 0.15 ratio is perhaps enough to determine keypad height. public static final double KEYBOARD_VISIBLE_RATIO = 0.15; private final KeyboardVisibilityLayoutListener keyboardVisibilityListener; private final View screen; private Runnable keyboardCloseListener; public KeyboardVisibilityDetector(final View screen) { this.screen = screen; keyboardVisibilityListener = new KeyboardVisibilityLayoutListener(this); screen.getViewTreeObserver().addOnGlobalLayoutListener(keyboardVisibilityListener); } public boolean isKeyboardVisible() { return keyboardVisibilityListener.isKeyboardVisible(); } public void setKeyboardCloseListener(Runnable keyboardCloseListener) { this.keyboardCloseListener = keyboardCloseListener; } public void closeKeyboard() { InputMethodManager imm = (InputMethodManager) screen.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); } private static class KeyboardVisibilityLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener { public static final int KEYBOARD_CLOSE_DURATION = 100; private View screen; private boolean isVisible = false; private KeyboardVisibilityDetector detector; public KeyboardVisibilityLayoutListener(KeyboardVisibilityDetector detector) { this.detector = detector; this.screen = detector.screen; } public boolean isKeyboardVisible() { return isVisible; } @Override public void onGlobalLayout() { int screenHeight = screen.getRootView().getHeight(); int screenBottomY = getScreenBottomY(screen); int keyboardHeight = screenHeight - screenBottomY; if (isKeyboardVisible(screenHeight, keyboardHeight)) { isVisible = true; } else { if (isVisible && detector.keyboardCloseListener != null) { NavigationApplication.instance.runOnMainThread(detector.keyboardCloseListener, KEYBOARD_CLOSE_DURATION); } isVisible = false; } } private boolean isKeyboardVisible(int screenHeight, int keypadHeight) { return keypadHeight > screenHeight * KEYBOARD_VISIBLE_RATIO; } private int getScreenBottomY(View screen) { Rect r = new Rect(); screen.getWindowVisibleDisplayFrame(r); return r.bottom; } } }