其他一些回答似乎过于复杂或不完整。这是一个面向未来访问者的通用答案。
在一个活动中
如果您有EditText的引用,那么很容易。
设置光标位置
editText.setSelection(index)
设定所选范围
editText.setSelection(startIndex, endIndex);
在IME(键盘)中
由于您无法直接访问EditText,因此从IME中操作会更加困难。但是,您可以使用InputConnection来设置光标位置和选择。
以下答案展示如何从您的InputMethodService
子类中获取输入连接:
InputConnection inputConnection = getCurrentInputConnection()
设置光标位置
inputConnection.setSelection(index, index)
设置选定的范围
inputConnection.setSelection(startIndex, endIndex);
将光标移动到开头
inputConnection.setSelection(0, 0)
将光标移动到末尾
ExtractedText extractedText = inputConnection.getExtractedText(new ExtractedTextRequest(), 0);
if (extractedText == null || extractedText.text == null) return;
int index = extractedText.text.length();
inputConnection.setSelection(index, index);
这种方法不能保证一定有效,因为如果EditText中的文本非常长,则提取出的文本不会是整个文本。不过,在大多数情况下,这种方法还是可以的。另一个选择是使用以下组合:
inputConnection.getTextBeforeCursor(numberOfChars, 0)
inputConnection.getSelectedText(0)
inputConnection.getTextAfterCursor(numberOfChars, 0)
其中numberOfChars
是一个较大的数字。
获取光标位置(或所选内容)
ExtractedText extractedText = inputConnection.getExtractedText(new ExtractedTextRequest(), 0);
int startIndex = extractedText.startOffset + extractedText.selectionStart;
int endIndex = extractedText.startOffset + extractedText.selectionEnd;
在extractedText
不能返回EditText
的全部文本的情况下,startOffset
会告诉你从哪个点开始提取的。然后你可以通过将startOffset
添加到提取文本的选择开头或结尾来获得实际的光标索引。
相对于当前位置移动光标
一旦你知道了光标的当前位置,就可以很容易地移动它。下面是将光标移到上一个单词的开头的示例。
BreakIterator boundary = BreakIterator.getWordInstance();
boundary.setText(extractedText.text.toString());
int preceding = boundary.preceding(extractedText.selectionStart);
int newIndex = (preceding == BreakIterator.DONE) ? selectionStart : preceding;
inputConnection.setSelection(newIndex, newIndex);
可以查看其他BreakIterator
选项,请在此处查看。
您还可以通过发送d-pad向下和向上事件来左右、上下移动。
向左移动
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT));
向右移动
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT));
向上移动
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_UP));
向下移动
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN));