Hopefully someone will find this answer helpful:
There is a workout to detect the exact height of the soft-keyboard which involve the Launcher Activity to send screen dimension to the game when a screen resize event occurs.
First, set a layout listener on the ViewTreeObserver of the rootView of your LauncherActivity:
public class AndroidLauncher extends AndroidApplication {
//...
public void setListenerToRootView() {
final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(keyboardLayoutListener);
}
private ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect visibleDisplayFrame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleDisplayFrame);
game.screenResize(visibleDisplayFrame.width(), visibleDisplayFrame.height());
}
};
//...
}
If you try to get the height of the root view, it will not work as most of the games are fullscreen.
Don't forget to add and remove the listener on appropriate occurrences:
@Override
protected void onCreate (Bundle savedInstanceState) {
//...
setListenerToRootView();
}
@Override
protected void onDestroy () {
super.onDestroy();
removeListenerToRootView();
}
public void removeListenerToRootView() {
final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(keyboardLayoutListener);
}
Next, declare the screenResize method inside the Game Class which will receive the dimensions and send it to the current screen:
public class YourGame extends Game {
//...
public ScreenBase currentScreen;
//...
public void screenResize(float width, float height) {
if(currentScreen != null)
currentScreen.onScreenResize(width, height);
}
//...
}
Every screen that involves a change must implement the onScreenResize method. Introduce an Abstract Base Class of screen that has an abstract method onScreenResize. The currentScreen variable must be set in the constructor:
public abstract class ScreenBase implements Screen {
//...
public ScreenBase(YourGame game) {
//...
this.game = game;
this.game.currentScreen = this;
//....
}
public abstract void onScreenResize(float width, float height);
Implement these in whichever screen you want:
public class LoginScreen extends ScreenBase {
//...
@Override
public void onScreenResize(final float width, final float height) {
if(Gdx.graphics.getHeight() > height) {
Gdx.app.log("LoginScreen", "Height of keyboard: " + (Gdx.graphics.getHeight() - height));
}
}
}