This works for me. Maybe this is always the best way for all versions.
It would be effective to make a property of keyboard visibility and observe this changes delayed because the onGlobalLayout method calls many times. Also it is good to check the device rotation and windowSoftInputMode
is not adjustNothing
.
boolean isKeyboardShowing = false; void onKeyboardVisibilityChanged(boolean opened) { print("keyboard " + opened); } // ContentView is the root view of the layout of this activity/fragment contentView.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect r = new Rect(); contentView.getWindowVisibleDisplayFrame(r); int screenHeight = contentView.getRootView().getHeight(); // r.bottom is the position above soft keypad or device button. // if keypad is shown, the r.bottom is smaller than that before. int keypadHeight = screenHeight - r.bottom; Log.d(TAG, "keypadHeight = " + keypadHeight); if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height. // keyboard is opened if (!isKeyboardShowing) { isKeyboardShowing = true onKeyboardVisibilityChanged(true) } } else { // keyboard is closed if (isKeyboardShowing) { isKeyboardShowing = false onKeyboardVisibilityChanged(false) } } } });