DialogFragment.dismiss() leaves keyboard on screen

Viewed 678

I'm observing a strange behaviour in my app where the on-screen keyboard lingers on the screen after dismissing a DialogFragment, obscuring the UI of the activity, despite the activity having android:windowSoftInputMode set to adjustResize in my manifest.

Here's what I have:

  • The activity is an AppCompatActivity
  • The activity's root element is CoordinatorLayout, which contains a ScrollView with attribute android:isScrollContainer="true"
  • In my manifest file, this activity has attribute android:windowSoftInputMode="adjustResize"
  • The activity has buttons that trigger an android.support.v4.app.DialogFragment to be shown, which contains an AutoCompleteTextView element.
  • By itself the keyboard doesn't show up when my dialog with its AutoCompleteTextView pops up, so I work around it by explicitly showing the keyboard on dialog show, and hiding it before dismissing the dialog.

My problem is that the keyboard hiding doesn't appear to be working correctly: after the dialog goes away, the keyboard stays, the activity's UI is not resized and so gets obscured by the keyboard, and the "Back" navigation button points left instead of down, as if it thought the keyboard was not being shown. Also, subsequently clicking on any textboxes in my activity then causes the keyboard to disappear, as if the keyboard realized it wasn't supposed to be there in the first place. When I comment out the dismiss() call, and dismiss my dialog by clicking anywhere outside of it, I see that the keyboard correctly goes away and everything works as expected.

The relevant code for my DialogFragment class definition is as follows:

 class DualSelectionDialogFragment : DialogFragment() {
    private var input: AutoCompleteTextView? = null
    [...]

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        [...]
        val builder = AlertDialog.Builder(context!!)
        val content = activity?.layoutInflater?.inflate(R.layout.select_dual_mode, null)
        [...]
        input = content?.findViewById<AutoCompleteTextView>(R.id.dual_autocomplete_input)?.apply {
            setAdapter(ArrayAdapter(context, android.R.layout.simple_list_item_1, [...]))
            setOnItemClickListener { _, view, _, _ ->
                [...]
                hideKeyboard(context, this)
                dismiss()
            }
        }
        [...]
        builder.setView(content).setCustomTitle(title)
        return builder.create()
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        dialog.window.setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE +
                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
    }

    [...]

    fun hideKeyboard(context: Context, view: View) {
        (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view.windowToken, 0)
    }
}

Am I doing something wrong here?

1 Answers

I had a similar problem with a DialogFragment containing two editText fields. Here is my hideKeyboard method called before dismiss() is called:

fun hideKeyboard(dialog: Dialog) {
        val focusedEditTextView = dialog.currentFocus

        val inputMethodManager = (focusedEditTextView?.context?.getSystemService(Context.INPUT_METHOD_SERVICE)) as InputMethodManager

        if (inputMethodManager.isActive) {
            inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }

This worked for me - tested on Android 9.1

Related