androideventsandroid-softkeyboard

How to capture the "virtual keyboard show/hide" event in Android?


I would like to alter the layout based on whether the virtual keyboard is shown or not. I've searched the API and various blogs but can't seem to find anything useful.

Is it possible?

Thanks!


Solution

  • 2020 Update

    This is now possible:

    On Android 11, you can do

    view.setWindowInsetsAnimationCallback(object : WindowInsetsAnimation.Callback {
        override fun onEnd(animation: WindowInsetsAnimation) {
            super.onEnd(animation)
            val showingKeyboard = view.rootWindowInsets.isVisible(WindowInsets.Type.ime())
            // now use the boolean for something
        }
    })
    

    You can also listen to the animation of showing/hiding the keyboard and do a corresponding transition.

    I recommend reading Android 11 preview and the corresponding documentation

    Before Android 11

    However, this work has not been made available in a Compat version, so you need to resort to hacks.

    You can get the window insets and if the bottom insets are bigger than some value you find to be reasonably good (by experimentation), you can consider that to be showing the keyboard. This is not great and can fail in some cases, but there is no framework support for that.

    This is a good answer on this exact question https://stackoverflow.com/a/36259261/372076. Alternatively, here's a page giving some different approaches to achieve this pre Android 11:

    https://developer.salesforce.com/docs/atlas.en-us.noversion.service_sdk_android.meta/service_sdk_android/android_detecting_keyboard.htm


    Note

    This solution will not work for soft keyboards and onConfigurationChanged will not be called for soft (virtual) keyboards.


    You've got to handle configuration changes yourself.

    http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange

    Sample:

    // from the link above
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    
        
        // Checks whether a hardware keyboard is available
        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
            Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
        } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
            Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
        }
    }
    

    Then just change the visibility of some views, update a field, and change your layout file.