Android —Keyboard State Listener
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.
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.
- 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 anactivity
,lifecycleOwner
, andlistener
. 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 anactivity
andlistener
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:
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! :)