Как зафиксировать составление текста в InputConnection, когда пользователь меняет выбор

Я делаю пользовательскую клавиатуру и должен установить написание текста перед его фиксацией. Это описано в этих вопросах и ответах.

Я знаю, как коммитить текст в целом

inputConnection.commitText("text", 1);

Но я не знаю, как это сделать, если пользователь изменит положение курсора, коснувшись другой части EditText. Наблюдая за другими клавиатурами, я знаю, что это возможно, потому что они это делают. Но на моей клавиатуре, если у меня есть

inputConnection.setComposingText("text", 1);

а затем измените положение курсора, составляющий диапазон останется. Любые будущие изменения заменят составной диапазон, а не будут введены в новую позицию курсора.

Сообщение Прослушиватель Android EditText для изменения положения курсора дает некоторые идеи о том, что вы могли бы сделать с EditText, но внутри пользовательской клавиатуры у меня нет доступа к EditText, кроме того, что дает мне InputConnection.

Как я могу узнать, когда курсор/выделение переместилось?

Я продолжаю находить ответ на свой вопрос после того, как начал его писать. Я опубликую ответ ниже.


person Suragch    schedule 20.07.2017    source источник


Ответы (2)


Редактор (EditText и т. д.) вызывает updateSelection в InputMethodManager, который, в свою очередь, уведомляет onUpdateSelection прослушиватель. Таким образом, клавиатура может переопределить onUpdateSelection и позаботиться о незавершенном отрезке композиции.

Для обработки незавершенного диапазона компоновки вы можете использовать finishComposingText на InputConnection. Это удалит составной диапазон и зафиксирует любой текст, который был в диапазоне.

Вот как это реализовано в пример программной клавиатуры Android:

/**
 * Deal with the editor reporting movement of its cursor.
 */
@Override public void onUpdateSelection(int oldSelStart, int oldSelEnd,
        int newSelStart, int newSelEnd,
        int candidatesStart, int candidatesEnd) {
    super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
            candidatesStart, candidatesEnd);

    // If the current selection in the text view changes, we should
    // clear whatever candidate text we have.
    if (mComposing.length() > 0 && (newSelStart != candidatesEnd
            || newSelEnd != candidatesEnd)) {
        mComposing.setLength(0);
        updateCandidates();
        InputConnection ic = getCurrentInputConnection();
        if (ic != null) {
            ic.finishComposingText();
        }
    }
}
person Suragch    schedule 20.07.2017

https://chromium.googlesource.com/android_tools/+/refs/heads/master/sdk/sources/android-25/android/widget/Editor.java#1604

int candStart = -1;
int candEnd = -1;
if (mTextView.getText() instanceof Spannable) {
  final Spannable sp = (Spannable) mTextView.getText();
  candStart = EditableInputConnection.getComposingSpanStart(sp);
  candEnd = EditableInputConnection.getComposingSpanEnd(sp);
}
person hojin    schedule 03.01.2021