Android —Keyboard State Listener

Shakiba E Nur
3 min readMay 19, 2023

As developers, we often encounter scenarios where we need to determine the state of the keyboard in our Android applications. Whether it’s for adjusting the layout, handling user input, or triggering specific actions, having a reliable keyboard state listener can greatly enhance the user experience.

In this article, we’ll explore how to create a keyboard state listener in Android and demonstrate its implementation.

Android Keyboard State Listener

Now let’s create a new android project and start…

First we will create an abstract class AutoActivityLifecycleCallback, it implements the Application.ActivityLifecycleCallbacks interface, which allows us to monitor the lifecycle events of activities in an Android application. The purpose of this abstract class is to provide a convenient way to listen specifically for the onActivityDestroyed() lifecycle event of a target activity.

abstract class AutoActivityLifecycleCallback internal constructor(
private val targetActivity: Activity
) : Application.ActivityLifecycleCallbacks {

override fun onActivityCreated(activity: Activity, bundle: Bundle?) {}

override fun onActivityStarted(activity: Activity) {}

override fun onActivityResumed(activity: Activity) {}

override fun onActivityPaused(activity: Activity) {}

override fun onActivityStopped(activity: Activity) {}

override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}

override fun onActivityDestroyed(activity: Activity) {
if (activity === targetActivity) {
targetActivity.application.unregisterActivityLifecycleCallbacks(this)
onTargetActivityDestroyed()
}
}
protected abstract fun onTargetActivityDestroyed()
}

Create a KeyboardStateEventListener class which defines a functional interface with a single method called onVisibilityChanged.

fun interface KeyboardStateEventListener {
fun onVisibilityChanged(isOpen: Boolean)
}

We will need an object class called KeyboardStateEvent that provides methods for detecting and handling changes in the visibility of the keyboard on an Android device.

You can find the full code of KeyboardStateEvent here.

  1. The class has two overloaded setEventListener methods, which allow you to register a keyboard state event listener with different combinations of parameters.
  • The first setEventListener method takes an activity, lifecycleOwner, and listener. It is intended to be used by fragments. It registers the event listener for detecting keyboard visibility changes on the specified activity and automatically removes the listener when the lifecycle owner (typically a fragment) is destroyed. This prevents memory leaks and crashes.
  • The second setEventListener method takes an activity and listener as parameters. It registers the event listener for detecting keyboard visibility changes on the specified activity and automatically removes the listener when the activity is destroyed.

2. The registerEventListener function is the core method that registers the event listener and returns an UnregisterEvent object.

3. The isKeyboardVisible function takes an activity as a parameter and determines if the keyboard is currently visible. It creates a Rect object to hold the visible display frame of the activity's window. It retrieves the root view of the activity and gets its location on the screen. It calculates the height difference between the screen height and the visible display frame’s height, taking into account the location of the root view. If the height difference is greater than a predefined minimum height ratio (KEYBOARD_MIN_HEIGHT_RATIO), it considers the keyboard to be visible and returns true. Otherwise, it returns false.

fun isKeyboardVisible(activity: Activity): Boolean {
val r = Rect()

val activityRoot = getActivityRoot(activity)

activityRoot.getWindowVisibleDisplayFrame(r)

val location = IntArray(2)
getContentRoot(activity).getLocationOnScreen(location)

val screenHeight = activityRoot.rootView.height
val heightDiff = screenHeight - r.height() - location[1]

return heightDiff > screenHeight * KEYBOARD_MIN_HEIGHT_RATIO
}

Here we will need a class UnregisterCallback that implements the UnregisterEvent interface. This class is used to unregister a previously registered event listener for keyboard state changes in Android.

Now you are good to use KeyboardStateEvent in your activity, fragment even in adapters.

For example:

class MainActivity : AppCompatActivity() {
private lateinit var mViewBinding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewBinding = ActivityMainBinding.inflate(layoutInflater)
KeyboardStateEvent.setEventListener(
this
) {isOpen->
if(isOpen) Toast.makeText(this,"Keyboard Open!",Toast.LENGTH_SHORT).show()
else Toast.makeText(this,"Keyboard closed!", Toast.LENGTH_SHORT).show()

}
setContentView(mViewBinding.root)
}
}

Demo:

Keyboard State Listener

Hope this article helps you. To check out Full Code, here is the Repository.

If you like the article do follow me for more interesting topics on Android Development.

Happy Coding! :)

--

--