Android IME,在EditText中设置光标位置

Ani*_*ket 9 android android-softkeyboard android-edittext

我正在使用软键盘,我需要在IME编辑文本中设置光标位置.

在此输入图像描述

如上图所示,我创建了软键盘,因为我们可以看到在编辑文本和当前光标位置输入了一些文本(由蓝色指示符显示).

我需要将光标位置设置在当前行的末尾(在我们的情况下,首先在图像中以红色显示的行的末尾)

我试过提供不同的功能InputConnection,我试过,

CharSequence seq = conn.getTextBeforeCursor(1000, 0);     // will get as much characters as possible on the left of cursor
Run Code Online (Sandbox Code Playgroud)

还有一件事,我还需要计算编辑文本中的行数(在我们的例子中是两行).

Sur*_*gch 5

其他一些答案似乎过于复杂或不完整。这是将来访客的一般答案。

在活动中

如果您有对EditText的引用,那么这很容易。

设置光标位置

editText.setSelection(index);
Run Code Online (Sandbox Code Playgroud)

设定选定范围

editText.setSelection(startIndex, endIndex);
Run Code Online (Sandbox Code Playgroud)

在IME(键盘)中

在IME中,这有点困难,因为您没有直接访问EditText的权限。但是,您可以使用InputConnection设置光标位置和选择。

下面的答案从您的InputMethodService子类中获取这样的输入连接:

InputConnection inputConnection = getCurrentInputConnection();
Run Code Online (Sandbox Code Playgroud)

设置光标位置

inputConnection.setSelection(index, index);
Run Code Online (Sandbox Code Playgroud)

设定选定范围

inputConnection.setSelection(startIndex, endIndex);
Run Code Online (Sandbox Code Playgroud)

将光标移到开头

inputConnection.setSelection(0, 0);
Run Code Online (Sandbox Code Playgroud)

将光标移到末尾

ExtractedText extractedText = inputConnection.getExtractedText(new ExtractedTextRequest(), 0);
if (extractedText == null || extractedText.text == null) return;
int index = extractedText.text.length();
inputConnection.setSelection(index, index);
Run Code Online (Sandbox Code Playgroud)

不能保证此方法有效,因为如果文本很长,提取的文本将不会是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;
Run Code Online (Sandbox Code Playgroud)

在该情况下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);
Run Code Online (Sandbox Code Playgroud)

在此处查看其他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));
Run Code Online (Sandbox Code Playgroud)

向右移

inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT));
Run Code Online (Sandbox Code Playgroud)

提升

inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_UP));
Run Code Online (Sandbox Code Playgroud)

下移

inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN));
Run Code Online (Sandbox Code Playgroud)


Ani*_*ket 2

嗨,朋友们,感谢您的赞赏。两天前我得到了解决方案,但无法更新我的答案。

为此我使用了下面的代码,

如果我们使用的 api 版本大于 10,

sendDownUpKeyEvents(0x0000007b);
Run Code Online (Sandbox Code Playgroud)

因为这个方法是在api 11中添加的。

如果我们使用的 api 版本低于 11,

if (getCurrentInputConnection() != null) {
                    CharSequence textAfter = getCurrentInputConnection().getTextAfterCursor(1024, 0);
                    if (!TextUtils.isEmpty(textAfter)) {
                        int newPosition = 1;
                        while (newPosition < textAfter.length()) {
                            char chatAt = textAfter.charAt(newPosition);
                            if (chatAt == '\n' || chatAt == '\r') {
                                break;
                            }
                            newPosition++;
                        }
                        if (newPosition > textAfter.length())
                            newPosition = textAfter.length();
                        try {
                            CharSequence textBefore = getCurrentInputConnection().getTextBeforeCursor(Integer.MAX_VALUE, 0);
                            if (!TextUtils.isEmpty(textBefore)) {
                                newPosition = newPosition + textBefore.length();
                            }
                            getCurrentInputConnection().setSelection(newPosition, newPosition);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
Run Code Online (Sandbox Code Playgroud)