onFocusChanged is being called when android device is rotated

Viewed 54

I want to restore the focus and keyboard state of a EditText when device is rotated. I have created a CustomEditText class which will save hasFocus() flag in bundle in onSaveInstanceState and restore it back in onRestoreInstanceState.

However, hasFocus() always return false in onSaveInstanceState. After further investigation, I found out that onFocusChanged is called before onSaveInstanceState and it sets the focus of the view to false even if that view was focused before rotation. That's why I am unable to store the focused state in bundle.

Below is my code:

open class CustomEditText(context: Context, attrs: AttributeSet): AppCompatEditText(context, attrs) {
    private var isFocused = false

    override fun onSaveInstanceState(): Parcelable? {
        val bundle = Bundle()
        bundle.putParcelable("super", super.onSaveInstanceState())
        // hasFocus() always return false
        bundle.putBoolean("hasFocus",  hasFocus())
        return bundle
    }

    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        isFocused = focused
    }

    override fun onRestoreInstanceState(state: Parcelable?) {
        var superState = state
        if (state is Bundle) {
            isFocused = state.getBoolean("hasFocus")
            superState = state.getParcelable("super")
            if (isFocused) {
                // Do something
            } else {

            }
        }
        super.onRestoreInstanceState(superState)
    }

    private fun handleKeyboardDismiss(event: KeyEvent?) {
        if (event.keyCode == KeyEvent.KEYCODE_ENTER) {
            clearFocus()
        }
        if (event.keyCode == KeyEvent.KEYCODE_BACK) {
            clearFocus()
        }
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        handleKeyboardDismiss(event)
        return super.onKeyUp(keyCode, event)
    }

    override fun onKeyPreIme(keyCode: Int, event: KeyEvent?): Boolean {
        handleKeyboardDismiss(event)
        return super.onKeyPreIme(keyCode, event)
    }
}

How can I store and restore focused state for that view?

If I set a breakpoint in onFocusChanged override method, then I am getting following stack trace.

onFocusChanged:73, CustomEditText
clearFocusInternal:7764, View (android.view)
clearFocus:7743, View (android.view)
clearFocus:1166, ViewGroup (android.view)
...
clearFocus:1166, ViewGroup (android.view)
setFlags:15742, View (android.view)
setVisibility:11372, View (android.view)
hide:358, Dialog (android.app)
onStop:727, DialogFragment (androidx.fragment.app)
performStop:3184, Fragment (androidx.fragment.app)
stop:640, FragmentStateManager (androidx.fragment.app)
...
0 Answers
Related