Currently in Android (as of Android 7.1.2), there is no out of the box option to get keyboard events. When we came across a scenario where this was needed, we had to come up with our own solution.
Our Problem
Our design included a main view with a ScrollView inside and some buttons below the scroll view.
This ScrollView contained a textbox for user editing. On entering text, the soft keyboard would open with the buttons below the scrollview being visible on top of the keyboard. This was taking up precious screen space.
To tackle this issue, we decided to hide the button when the Soft keyboard was shown. Unfortunately there was no easy way to find if softKeyboard is shown or hidden.
The Solution
After searching multiple sources, we found one particular method that we could modify to fit for our use case.
We decided to use the addOnGlobalLayoutListener to the root view and monitor for changes in root view’s height has shrunk from its original height meaning that the soft keyboard was opened.
If the height of the app has reduced from its maximum height then the keyboard must have been opened else the keyboard is hidden.
Make sure there are no intensive tasks onKeyboardVisibilityChanged method as it can be called multiple times.
Code
Variables
static int mAppHeight;
static int currentOrientation = -1;
Method
public static void setKeyboardVisibilityListener(final Activity activity, final KeyboardVisibilityListener keyboardVisibilityListener) {
final View contentView = activity.findViewById(android.R.id.content);
contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private int mPreviousHeight;
@Override
public void onGlobalLayout() {
int newHeight = contentView.getHeight();
if (newHeight == mPreviousHeight)
return;
mPreviousHeight = newHeight;
if (activity.getResources().getConfiguration().orientation != currentOrientation) {
currentOrientation = activity.getResources().getConfiguration().orientation;
mAppHeight =0;
}
if (newHeight >= mAppHeight) {
mAppHeight = newHeight;
}
if (newHeight != 0) {
if (mAppHeight > newHeight) {
// Height decreased: keyboard was shown
keyboardVisibilityListener.onKeyboardVisibilityChanged(true);
} else
{
// Height increased: keyboard was hidden
keyboardVisibilityListener.onKeyboardVisibilityChanged(false);
}
}
}
});
}
Interface
public interface KeyboardVisibilityListener {
void onKeyboardVisibilityChanged(boolean keyboardVisible);
}
//to call from the view controller set keyboard listener setKeyboardVisibilityListener with the activity and listener parameter. Utils is the class name where we have written our code.
Utils.setKeyboardVisibilityListener(activity, this);
//Override the onKeyboardVisibilityChanged method to perform your changes
@Override
public void onKeyboardVisibilityChanged(boolean keyboardVisible) {
if (keyboardVisible) {
//hide the button if keyboard is shown
bottomView.setVisibility(View.GONE);
}else {
//show the button if keyboard is hidden
bottomView.setVisibility(View.VISIBLE);
}
}
Limitations of the solution
This solution uses global layout listener which means this code block will be called whenever the screen is updated. Hence make sure you don’t do any resource intensive task in this block.
References:
Modified code from following answers
https://stackoverflow.com/questions/24388492/listen-for-keyboard-show-or-hide-event-in-android
https://stackoverflow.com/questions/25216749/softkeyboard-open-and-close-listener-in-an-activity-in-android