我有一个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
-子类中重写了以下方法:
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()
也会在非用户输入时被触发,所以这也不是我想要的。
事实证明,上述InputConnectionWrapper
的用法是完全正确的。然而,commitText()
永远不会被调用(特殊情况除外),因为还有其他方法在键入过程中使用。主要是setComposingText()
和sendKeyEvent()
。但是,覆盖很少使用的方法(如deleteSurroundingText()
或commitText()
)也很重要,以确保捕获每个用户输入。
布伦德尔在聊天中建议你使用文本监视器。
使用TextWatcher,在修改edittext时断开连接,完成后重新连接。这样,您就不会触发无限的调用。