pressing software back button will close entire activity while keyboard is visible

481 Views Asked by At

I experienced weird bug in my app on some of my screens and I dont know what is causing this (I have multiple screens with same implementation, but its happening only in this one). When I display virtual keyboard on EditText focus and I press back button, it will not close keyboard, but instead it will act as back button and close current screen (I have ViewPager so it will redirect to previous page). I logged onBackPressed and it is called instantly as I press back button while virtual keyboard is visible.

Field XML:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/manufactureNumberLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/TextInputLayoutStyle"
    app:errorEnabled="true"
    android:hint='@{CustomRes.stringValues["manufacture_field_hint"]}' >

    <com.project.utils.InterceptableTextInputEditText
        android:id="@+id/manufactureNumberEt"
        android:layout_width="match_parent"
        android:textAllCaps="true"
        android:digits='@{CustomRes.stringValues["manufacture_available_nums_loc"]}'
        android:maxLength="10"
        app:errorEnabled="true"
        android:singleLine="true"
        style="@style/TextInputEditTextStyle" />

</com.google.android.material.textfield.TextInputLayout>

Code:

class InterceptableTextInputEditText : TextInputEditText {

    @SuppressLint("ClickableViewAccessibility")
    constructor(context: Context) : super(context)

    @SuppressLint("ClickableViewAccessibility")
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    @SuppressLint("ClickableViewAccessibility")
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onKeyPreIme(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK){
            clearFocus()
        }
        return false
    }
}


manufactureNumEt.apply {
    onFocusChange {
        if (isFocused){
            movetoEnd()
              post(200){
                app.showKeyboard(a)
              }
        } else {
            app.hideKeyboard(this)
        }
    }
    onEditorAction {
        picker?.openPicker()
    }
    afterTextChanged {
        validateData()
    }
}


fun hideKeyboard(view: View){
    App.log("Application: keyboard - hideKeyboard")
    val imm = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(view.windowToken, 0)
}

fun showKeyboard(activity: BaseActivity? = null){
    App.log("Application: keyboard - showKeyboard")
    val imm = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    activity?.let {
        if (!activity.virtualKbIsShown){
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
        }
    }?:kotlin.run {
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
    }
}
1

There are 1 best solutions below

0
On

Try to override onBackPressed() in your Activity:

override onBackPressed() {
   if(key board is open) 
   {
     your keyboard hide method -> hideKeyboard() 
   } else {
     super.onBackPressed()
   }
}

When I search 'how to detect key board is open on screen', I found this answer which might be more detailed: https://stackoverflow.com/a/37115149/7675215