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

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

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

inputConnection.commitText("text", 1);

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

inputConnection.setComposingText("text", 1);

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

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

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

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

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();
        }
    }
}

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);
}
Другие вопросы по тегам