The documentation for InputConnection.commitText(CharSequence text, int newCursorPosition)
says that newCursorPosition
means:
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.
In this example, if I enter two characters, then position the cursor between them like this
and then enter another character, it doesn't matter if I set newCursorPosition
to 0
or 1
. The cursor is always at the end of the insertion. For example calling
inputConnection.commitText("aaa", 0);
or
inputConnection.commitText("aaa", 1);
Both show the cursor like this:
If I do -1
with
inputConnection.commitText("aaa", -1);
I get this
The 1
and -1
results are expected as per the documentation. Why doesn't 0
put the cursor at the beginning of the insertion? I would expect 0
should be like this
inputConnection.commitText("aaa", 0);
but it isn't. Why not?
This looks like a defect in the code, but you be the judge.
Take a look at replaceText() in BaseInputConnection
. I believe that this is the code that places the cursor after insertion. (replaceText()
is called from commitText())
.
In the referenced code, a
is the selection start. b
is the selection end. Since there is no selection in the example and the cursor is at index 1 then a == b == 1
. Also, the new text (aaa) is not inserted (replacing a selection [a,b]) until after the cursor is moved to the new selection.
Selection.setSelection(content, newCursorPosition)
sets the cursor position, so for 0 and 1 to produce identical positioning in your example, I would expect the derived value of newCursorPosition
to be the same for both inputs.
With the cursor positioned between the two 8's at position 1, let's think through the following code:
if (newCursorPosition > 0) {
newCursorPosition += b - 1;
} else {
newCursorPosition += a;
}
For your input of 1, newCursorPosition
> 0, so newCursorPosition = newCursorPosition + 1 - 1 or 1.
For your input of 0, newCursorPosition
is not = 0, so newCursorPosition = newCursorPosition + a (0 + 1) or 1.
Since both inputs produce the same value, I would expect Selection.setSelection(content, newCursorPosition)
to produce the results you see.
I have not followed the code exactly to this location, but I believe that this is the problem. I have followed the execution paths in BaseInputConnection
for newCursorPosition = 0
and newCursorPosition = 1
on a Pixel emulator with API 21 and what is outlined above does hold.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With