how to change a soft keyboard's height at run-time?
Categories:
Dynamically Adjusting Android Soft Keyboard Height at Runtime

Learn how to programmatically control and modify the height of the Android soft keyboard to enhance user experience and UI adaptability in your applications.
Adjusting the soft keyboard's height at runtime in Android applications can be crucial for creating a seamless user experience, especially when dealing with complex layouts or when specific UI elements need to remain visible above the keyboard. While Android handles keyboard visibility and resizing automatically in many cases, there are scenarios where developers need more granular control over its dimensions. This article explores various techniques to achieve dynamic keyboard height adjustment, focusing on practical implementation methods.
Understanding Keyboard Behavior and Window Insets
Before diving into code, it's essential to understand how Android manages the soft keyboard. When the keyboard appears, it typically triggers a window resize or a pan effect, depending on the windowSoftInputMode
setting in your AndroidManifest.xml
. Modern Android versions (API 29+) leverage WindowInsets
to provide detailed information about system bars and the keyboard. This is the recommended approach for handling keyboard visibility and size changes.
flowchart TD A[User focuses on EditText] --> B{Soft Keyboard Appears} B --> C{Window Insets Change} C --> D{App receives Insets Callback} D --> E{Calculate Keyboard Height} E --> F{Adjust UI Layout (e.g., Padding/Margin)} F --> G[Enhanced User Experience]
Flow of Keyboard Appearance and UI Adjustment using Window Insets
Implementing Dynamic Height Adjustment with Window Insets
The most robust and modern way to detect and react to keyboard height changes is by using WindowInsets
listeners. This approach is particularly effective for API level 29 and above. You can listen for changes in the WindowInsets
and extract the keyboard's height from the ime()
(Input Method Editor) insets.
import android.graphics.Rect
import android.os.Build
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsAnimation
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
fun setupKeyboardHeightListener(view: View, onKeyboardHeightChanged: (Int) -> Unit) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
view.setOnApplyWindowInsetsListener { v, insets ->
val imeVisible = insets.isVisible(WindowInsets.Type.ime())
val imeHeight = insets.getInsets(WindowInsets.Type.ime()).bottom
onKeyboardHeightChanged(if (imeVisible) imeHeight else 0)
insets
}
// Request insets to be dispatched
ViewCompat.requestApplyInsets(view)
} else {
// Fallback for older APIs (less reliable)
view.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
view.getWindowVisibleDisplayFrame(r)
val screenHeight = view.rootView.height
val keyboardHeight = screenHeight - r.bottom
onKeyboardHeightChanged(keyboardHeight)
}
}
}
Kotlin function to set up a keyboard height listener using WindowInsets (API 30+) and a fallback for older APIs.
WindowInsets
, ensure your activity's windowSoftInputMode
is set to adjustResize
or adjustPan
to allow the system to dispatch the correct insets. For adjustResize
, the window size changes, providing accurate keyboard height. For adjustPan
, the window pans, and you might need to calculate the difference.Applying the Keyboard Height to UI Elements
Once you have the keyboard's height, you can apply it to various UI elements. Common use cases include adjusting the padding of a RecyclerView
or ScrollView
so that the last items are not obscured, or moving a Button
or EditText
above the keyboard. This example demonstrates adjusting the bottom padding of a RecyclerView
.
class MyActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var rootView: View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
recyclerView = findViewById(R.id.my_recycler_view)
rootView = findViewById(android.R.id.content)
setupKeyboardHeightListener(rootView) { keyboardHeight ->
// Apply the keyboard height as bottom padding to the RecyclerView
recyclerView.setPadding(0, 0, 0, keyboardHeight)
// Optionally, scroll to the last item if it's a chat-like interface
// recyclerView.scrollToPosition(adapter.itemCount - 1)
}
}
// ... setupKeyboardHeightListener function as defined previously ...
}
Example of an Activity using the keyboard height listener to adjust RecyclerView padding.
onKeyboardHeightChanged
callback. For older API levels, addOnGlobalLayoutListener
can be called many times, so ensure your logic is efficient and doesn't cause infinite loops or excessive redraws.