使用 InputConnection.commitText 将光标设置在插入文本的开头

Setting the cursor at the start of inserted text with InputConnection.commitText

InputConnection.commitText(CharSequence text, int newCursorPosition) 的文档说 newCursorPosition 表示:

int: The new cursor position around the text, in Java characters. If > 0, this is relative to the end of the text - 1; if <= 0, this is relative to the start of the text. So a value of 1 will always advance the cursor to the position after the full text being inserted. Note that this means you can't position the cursor within the text, because the editor can make modifications to the text you are providing so it is not possible to correctly specify locations there.

this example中,如果我输入两个字符,那么像这样将光标放在它们之间

然后再输入一个字符,我把newCursorPosition设置成0或者1都没有关系。光标总是在插入的末尾。例如调用

inputConnection.commitText("aaa", 0);

inputConnection.commitText("aaa", 1);

两者都这样显示光标:

如果我 -1

inputConnection.commitText("aaa", -1);

我明白了

1-1 结果符合文档的预期。 为什么 0 不把光标放在插入的开头? 我希望 0 应该是这样的

inputConnection.commitText("aaa", 0);

但事实并非如此。为什么不呢?

这看起来像是代码中的一个缺陷,但你是判断者。

看看 BaseInputConnection 中的 replaceText()。我相信这是插入后放置光标的代码。 (replaceText()commitText()) 调用。

在参考代码中,a是选择开始。 b为选择结束。由于示例中没有选择并且光标位于索引 1,因此 a == b == 1。此外,在光标移动到新选择之前,不会插入新文本 (aaa)(替换选择 [a,b])。

Selection.setSelection(content, newCursorPosition) 设置光标位置,因此对于 0 和 1 在您的示例中产生相同的定位,我希望两个输入的 newCursorPosition 的派生值相同。

将光标定位在位置 1 的两个 8 之间,让我们思考一下以下代码:

if (newCursorPosition > 0) {
    newCursorPosition += b - 1;
} else {
    newCursorPosition += a;
}

对于你输入的 1,newCursorPosition > 0,所以 newCursorPosition = newCursorPosition + 1 - 1 or 1.

对于你输入的0,newCursorPosition不是=0,所以newCursorPosition = newCursorPosition + a (0 + 1) or 1.

由于两个输入产生相同的值,我希望 Selection.setSelection(content, newCursorPosition) 产生您看到的结果。

我没有完全按照代码到这个位置,但我相信这就是问题所在。我已经按照 BaseInputConnection 中的执行路径执行 newCursorPosition = 0newCursorPosition = 1 在具有 API 21 的 Pixel 模拟器上,上面概述的内容确实成立。