Как использовать InputConnectionWrapper?

У меня есть EditText. Теперь я хочу получить все изменения, сделанные пользователем, этому EditText и работать с ними, прежде чем вручную вставить их в EditText. Я не хочу, чтобы пользователь напрямую менял текст в EditText. Это должно выполняться только моим кодом (например, с помощью replace() или setText()).

Я немного искал и нашел интересный класс с именем InputConnectionWrapper. Согласно javadoc он должен выступать в качестве прокси для данного InputConnection. Поэтому я подклассифицировал его следующим образом:

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;
    }

}

Чтобы инициализировать оболочку, я перезаписал следующий метод в моем EditText -subclass:

public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    InputConnection con = super.onCreateInputConnection(outAttrs);
    EditTextInputConnection connectionWrapper = new EditTextInputConnection(con, true);
    return connectionWrapper;
}

Однако commitText() никогда не вызывается. Вызывается onCreateInputConnection() и конструктор EditTextInputConnection, но никогда commitText(), хотя он должен быть, когда я ввожу какой-либо текст в поле. По крайней мере, это то, как я понимаю использование InputConnectionWrapper. Или я не прав?

Изменить: Кажется, что commitText() вызывается только для специальных символов, таких как ".", "" и т.д. Как я понимаю, исходный код Android для всех других символов InputConnectionWrapper.sendKeyEvent() должен быть вызван, но это не так... Я абсолютно застрял в этом вопросе. Я уже пробовал EditText.onKeyPreIme(), но это работает только на аппаратных клавиатурах. Так что нет альтернативы... Я не совсем понимаю, почему Android управляет мягкими клавиатурами, отличными от аппаратных клавиатур. EditText.onTextChanged() также увольняется с не-пользовательского ввода, так что это тоже не то, что я ищу.

Ответ 1

Оказалось, что вышеупомянутое использование InputConnectionWrapper было абсолютно правильным. Тем не менее, commitText() никогда не вызывается (за исключением особых случаев), так как существуют другие методы, которые используются при наборе текста. Это в основном setComposingText() и sendKeyEvent(). Тем не менее, также важно перезаписать редко используемые методы, такие как deleteSurroundingText() или commitText(), чтобы убедиться, что пользовательский ввод каждого.

Ответ 2

Blundell предложил в чате, что вы используете TextWatcher. Проверьте, не поможет ли это вам.

Ответ 3

Используйте TextWatcher, отключите его, когда вы изменяете свой edittext и снова подключаете его, когда это будет сделано. Таким образом, вы не будете запускать бесконечные вызовы.