如何使用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
子类中重写了以下方法:
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()
也会在非用户输入时触发,所以这也不是我正在寻找的。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
事实证明,上述
InputConnectionWrapper
的用法是完全正确的。但是,commitText()
永远不会被调用(特殊情况除外),因为还有其他方法在键入期间使用。主要是setCompositingText()
和sendKeyEvent()
。但是,覆盖很少使用的方法(例如deleteSurroundingText()
或commitText()
)也很重要,以确保捕获每个用户输入。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.Blundell 在聊天中建议您使用 TextWatcher。检查这是否对您有帮助。
Blundell suggested on the chat that you use a TextWatcher. Check if this helps you out.
使用 TextWatcher,在修改编辑文本时断开连接,并在完成后重新连接。这样,您就不会触发无限调用。
Use a TextWatcher, disconnect it when you're modifying your edittext and reconnect it when done. This way, you won't trigger infinite calls.