I would like to create a custom text editor view in Android, with customizable key controls, meaning that I need to handle all software keyboard key events.
To do this, I can extend View
and override its onKeyDown
event. However, I would also like to preserve the user's full software keyboard functionality, e.g. suggestions and glide-typing, which seems to only work if I properly override onCreateInputConnection
like so:
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
outAttrs.inputType = InputType.TYPE_CLASS_TEXT
return object : BaseInputConnection(this, true) { ... }
}
Unfortunately, the InputConnection
seems to eat all the key events and block the key listener methods like onKeyDown
from being called, whereas I would like to listen to key events and use an InputConnection
(to allow full soft keyboard functionality) at the same time.
The only workaround I have found is using a TextWatcher
to listen to text change events, but I don't feel this is as flexible or simple as I need it to be; I need full and direct access to all key presses.
I believe this is possible because this is exactly how an input
element in a WebView
works: I can listen to its key events and the user can input text with suggestions or glide-typing at the same time. In fact, I am considering using a WebView
after all, but I don't see why it shouldn't be possible to do this without one.
How can I implement this behavior in Android, in either a View or a Composable?
CodePudding user response:
KeyEvents don't exist when using a soft keyboard. Almost every soft keyboard uses InputConnection.commitText() to send characters or even words at a time. KeyEvents are only really generated by hardware keyboards, bluetooth keyboards, and physical keys like volume.
If you want to look for changes to text, implement the commitText() function and see what's sent over there. There's one or two other functions like deleteSurroundingText you'd need to override as well to get delete presses.