I have an EditText
. Now I want to get all changes made by the user to this EditText
and work with them before manually inserting them into the EditText
. I don't want the user to directly change the text in the EditText
. This should only be done by my code (e.g. by using replace()
or setText()
).
I searched a bit and found an interesting class named InputConnectionWrapper
. According to the javadoc it shall act as a proxy for a given InputConnection
. So I subclassed it like this:
private class EditTextInputConnection extends InputConnectionWrapper {
public EditTextInputConnection(InputConnection target, boolean mutable) {
super(target, mutable);
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
// some code which takes the input and manipulates it and calls editText.getText().replace() afterwards
return true;
}
}
To initialize the wrapper I overwrote the following method in my EditText
-subclass:
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection con = super.onCreateInputConnection(outAttrs);
EditTextInputConnection connectionWrapper = new EditTextInputConnection(con, true);
return connectionWrapper;
}
However, commitText()
never gets called. The onCreateInputConnection()
gets called and the constructor of EditTextInputConnection
also, but never commitText()
, altough it should be, when I enter some text into the field. At least, that's how I understand the usage of InputConnectionWrapper
. Or am I wrong?
Edit: It seems, that commitText()
is only called for special characters like "."," " etc. As I understand the Android sourcecode for all other characters InputConnectionWrapper.sendKeyEvent()
should be called, but that's not the case... I'm absolutely stuck at this point. I already tried EditText.onKeyPreIme()
, but this only works on hardware keyboards. So that's no alternative... I don't really understand, why Android handles soft keyboards that different from hardware keyboards.
EditText.onTextChanged()
gets also fired on non-user input, so this is also not, what I'm looking for.
Blundell suggested on the chat that you use a TextWatcher. Check if this helps you out.
Use a TextWatcher, disconnect it when you're modifying your edittext and reconnect it when done. This way, you won't trigger infinite calls.
It turned out, that the above usage of the
InputConnectionWrapper
was totally correct. However,commitText()
gets never called (except for special cases), as there are other methods, which are used during typing. These are mainlysetComposingText()
andsendKeyEvent()
. However, it is also important to overwrite seldom used methods likedeleteSurroundingText()
orcommitText()
to make sure to catch every user input.