12

I used SOFT_INPUT_ADJUST_RESIZE in order to show all content when keyboard pops up. Following documentation, I added new code pieces:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    requireActivity().window.setDecorFitsSystemWindows(false)
}

and

binding.constraintLayoutRoot.setOnApplyWindowInsetsListener { _, windowInsets ->
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        val insets = windowInsets.getInsets(WindowInsets.Type.ime() or WindowInsets.Type.systemGestures())
        insets
    }

    windowInsets
}

For some reason, view does not resize based on the fact if the keyboard appears or not.

MaaAn13
  • 264
  • 5
  • 24
  • 54

6 Answers6

15

As per google developers from Android API 30, they have deprecated it and provided us with a workaround setDecorFitsSystemWindows. But this will not work below Android 30 for below 30 you have to use the same method as before.

How it works: When setDecorFitsSystemWindows is true the framework will check SYSTEM_UI_LAYOUT_FLAGS as well the WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE flag and fits content according to these flags.

But when it is set to False the framework will not fit the content view to the insets and will check your WindowInsets to set the content view.

First, you have to define your windowsInsets which it can use

binding.root.setOnApplyWindowInsetsListener { _, windowInsets ->
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val imeHeight = windowInsets.getInsets(WindowInsets.Type.ime()).bottom
            binding.root.setPadding(0, 0, 0, imeHeight)
        }
        windowInsets
    }

and then when you want your screen to use ADUST_RESIZE set false

setDecorFitsSystemWindows(false)

When you want back to normal set true

setDecorFitsSystemWindows(true)

Managing for API 30 above and below use conditions

var shouldResize = false // false will resize
    binding.button.setOnClickListener {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window.setDecorFitsSystemWindows(shouldResize)
            shouldResize = shouldResize.not()
        } else {
            if (shouldResize.not()) {
                window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
            } else {
                window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
            }
        }
    }

Reference link:

Android SOFT_INPUT_ADJUST_RESIZE
Android setDecorFitsSystemWindows

Tejas Soni
  • 404
  • 3
  • 4
  • 1
    What is the point of updating `shouldResize` to `shouldResize = shouldResize.not()`? – Bitwise DEVS Jul 28 '22 at 18:42
  • oh great. I have an app that needs to adjust one way when entering text into one EditText, and adjust a different way when entering text into a different EditText, and now I will need spaghetti code to sort them both out... – Phlip Feb 12 '23 at 15:58
7

Can you try doing the following, I think we have to manually add the padding for the keyboard now.

binding.root.setOnApplyWindowInsetsListener { _, windowInsets ->
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        val imeHeight = windowInsets.getInsets(WindowInsets.Type.ime()).bottom
        binding.root.setPadding(0, 0, 0, imeHeight)
        val insets = windowInsets.getInsets(WindowInsets.Type.ime() or WindowInsets.Type.systemGestures())
        insets
    }

    windowInsets
}
che10
  • 2,176
  • 2
  • 4
  • 11
4

The simplest solution is to add the following to AndroidManifest.xml.

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="adjustResize" />
Tatsuya Fujisaki
  • 1,434
  • 15
  • 18
4

In case you are using BottomSheetDialogFragment, be sure to call methods on requireDialog().window instead of requireActivity().window

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  requireDialog().window?.let { WindowCompat.setDecorFitsSystemWindows(it, false) }
} else {
  @Suppress("DEPRECATION")
  requireDialog().window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
}
Mihail Ya
  • 361
  • 3
  • 6
3
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        ViewCompat.setOnApplyWindowInsetsListener(requireDialog().window?.decorView!!) { _, insets ->
            val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
            val navigationBarHeight =
                insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
            viewBinding.root.setPadding(0, 0, 0, imeHeight - navigationBarHeight)
            insets
        }
    } else {
        @Suppress("DEPRECATION")
        requireDialog().window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
    }

For BottomSheetDialogFragment(), please like this answer if you also facing the same issue. Works perfect for me, tested. By the way, paste above code in onViewCreated()

Ashton
  • 2,425
  • 2
  • 22
  • 26
0

Could not get any of these to work with dialogs. For activities Tatsuya Fujisaki's solution works fine, but for dialogs to resize the layout needs to match the parent

val window = this.window
window?.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)
Rowan Berry
  • 171
  • 7