Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use InputConnectionWrapper?

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.

like image 890
ubuntudroid Avatar asked Jul 08 '11 14:07

ubuntudroid


2 Answers

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 mainly setComposingText() and sendKeyEvent(). However, it is also important to overwrite seldom used methods like deleteSurroundingText() or commitText() to make sure to catch every user input.

like image 99
ubuntudroid Avatar answered Nov 15 '22 14:11

ubuntudroid


Blundell suggested on the chat that you use a TextWatcher. Check if this helps you out.

like image 31
Lukas Knuth Avatar answered Nov 15 '22 13:11

Lukas Knuth