EditText still receives hardware keyboard input after being disabled, and onKey is not called — why does this happen?
I am working on an Android app where I dynamically create an EditText and want to stop accepting input after a certain condition (for example, after 5 seconds).
My expectation is:
Once the EditText is disabled (isEnabled = false) or focus is cleared, it should no longer receive input.
If the user presses keys on a hardware keyboard, at the very least I should see those key events in the EditText's KeyListener
However, what I am observing is confusing.
I explicitly disable the EditText:
searchBox.isEnabled = false
Even after disabling it:
Characters typed on a physical keyboard still appear inside the EditText
setOnKeyListener on the EditText is never called
I do see key events in the Activity:
override fun dispatchKeyEvent(event: KeyEvent): Boolean { Log.d("POC", "Key received: ${event.keyCode}") return super.dispatchKeyEvent(event) }
So:
dispatchKeyEvent() is hit
but the EditText still updates its text
and onKey on the EditText never fires
class MainActivity : AppCompatActivity() { private lateinit var root: LinearLayout private lateinit var button: Button private lateinit var loading: TextView private lateinit var searchBox: EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) root = LinearLayout(this).apply { orientation = LinearLayout.VERTICAL isFocusable = true isFocusableInTouchMode = true } button = Button(this).apply { text = "Select Company" } loading = TextView(this).apply { text = "Loading..." visibility = View.GONE } searchBox = EditText(this).apply { hint = "Search Company" visibility = View.GONE } // Key listener on EditText searchBox.setOnKeyListener { _, keyCode, event -> Log.d( "POC", "EditText onKey: ${KeyEvent.keyCodeToString(keyCode)}, action=${event.action}" ) false } // Key listener on root container root.setOnKeyListener { _, keyCode, event -> Log.d( "POC", "Root onKey: ${KeyEvent.keyCodeToString(keyCode)}, action=${event.action}" ) false } root.addView(button) root.addView(loading) root.addView(searchBox) setContentView(root) button.setOnClickListener { startFlow() } } private fun startFlow() { // Remove focus during loading button.clearFocus() root.clearFocus() root.isFocusable = false root.isFocusableInTouchMode = false loading.visibility = View.VISIBLE searchBox.visibility = View.GONE // Simulate async work root.postDelayed({ // Restore focusability root.isFocusable = true root.isFocusableInTouchMode = true searchBox.isFocusable = true searchBox.isFocusableInTouchMode = true searchBox.isEnabled = true loading.visibility = View.GONE searchBox.visibility = View.VISIBLE // Explicitly give focus to EditText searchBox.requestFocus() }, 3000) // Disable EditText after 8 seconds searchBox.postDelayed({ Log.d("POC", "Disabling EditText") searchBox.isEnabled = false }, 8000) } override fun dispatchKeyEvent(event: KeyEvent): Boolean { Log.d( "POC", "Activity dispatchKeyEvent: code=${event.keyCode}, char='${event.unicodeChar.toChar()}'" ) return super.dispatchKeyEvent(event) } }