Setting windowSoftInputMode for a single fragment

Every android developer knows that he/she can set windowSoftInputMode inside AndroidManifest.xml as an attribute for each activity to manage the behaviour related to the software keyboard.

Setting the value in AndroidManifest.xml

You may know that it’s pretty simple to do so at runtime by calling the

activity?.window?.setSoftInputMode(mode)

method on an activity instance.

But what if you need to change the soft input mode in just the current fragment and not the whole activity?

You may wonder why you would do so: just imagine that you implemented a single activity navigation model and you need some fragments to behave differently from the rest of the app.

What would you want to do is tipically:

  • save the current softInputMode somewhere
  • set the new softInputMode when your fragment is created
  • restore the old softInputMode when the fragment is destroyed

In doing so, you will notice that while a setSoftInputMode method is available on the Window object, we don’t have a getter method as well.

With a little effort you will find that current softInputMode can be accessed by getting it from the window’s attributes manully, like this:

activity?.window?.attributes?.softInputMode

What I did for my apps is to create a convenience extension method on the Window object

fun Window.getSoftInputMode() : Int {
return attributes.softInputMode
}

You won’t actually need to do so but I did it for the sake of readability and for symmetry with the setter method.

I found it to be useful to simply writing

val mode = activity?.window?.getSoftInputMode()

To wrap it all up let’s see how to use this in the sample below:

class ExampleFragment : Fragment() {
private lateinit var originalMode : Int
    override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
        originalMode = activity?.window?.getSoftInputMode()
        activity?.window?.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN
)
}

override fun onDestroy() {
super.onDestroy()
activity?.window?.setSoftInputMode(originalMode)
}
}

As you can see, the onCreate method saves the current softInputMode inside the originalMode variable then it sets the new value.

To ensure that everything outside the ExampleFragment will still work as before, the onDestroy method reverts softInputMode to the original value.

That’s all folks!