Как обновить извлеченный текст в пользовательском представлении редактора - PullRequest
0 голосов
/ 13 июня 2018

Я создал специальный редактор для вертикального монгольского текста.Окруженные представления показывают мой пользовательский редактор.Эти клавиатуры внизу являются системными клавиатурами.

enter image description here

Когда системная клавиатура вводит в нее текст в горизонтальной ориентации, клавиатура, вероятно, будет отображатьизвлеченный текстовый вид, а не мой пользовательский вид редактора.Представление в кружке ниже - это извлеченное текстовое представление (которое не обновляется моим пользовательским редактором).

enter image description here

Мне нужно каким-то образом отправлять обновления из моеговид на менеджер метода ввода.Об этом говорится в InputConnection документации :

Авторы редактора: как правило, старайтесь соблюдать поля в запросе на количество возвращаемых символов, но еслипроизводительность или удобство диктуют иначе, пожалуйста, не стесняйтесь делать то, что наиболее подходит для вашего случая.Кроме того, если установлен флаг GET_EXTRACTED_TEXT_MONITOR, вы должны вызывать InputMethodManager.updateExtractedText(View, int, ExtractedText) всякий раз, когда звоните InputMethodManager.updateSelection(View, int, int, int, int).

Я изучал исходный код, связанный с извлеченным текстом

но я потерялся.

Вот самое близкое, что я получил.Это метод внутри моего пользовательского редактора.

private void reportExtractedText() {

    // TODO we should be modifying this based on an ExtractedTextRequest

    ExtractedText et = new ExtractedText();
    final CharSequence content = getText();
    final int length = content.length();
    et.partialStartOffset = 0;
    et.partialEndOffset = length;
    et.startOffset = 0;
    et.selectionStart = getSelectionStart();
    et.selectionEnd = getSelectionEnd();
    et.flags = 0;
    et.text = content.subSequence(0, length);

    // FIXME: should be returning this from the ExtractedTextRequest
    int requestToken = 0;

    InputMethodManager imm = (InputMethodManager) getContext()
            .getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm == null) return;
    imm.updateExtractedText(this, requestToken, et);
}

Когда я нахожусь в моем редакторе, у меня нет ссылки на ExtractedTextRequest, который следует использовать для изменения того, что я включаю в извлеченный текстupdate.

Вот еще один метод внутри моего подкласса BaseInputConnection (слегка измененный с здесь ).У меня есть доступ к ExtractedTextRequest, но это не то место, откуда я вызываю обновления.Это приведет к тому, что извлеченное текстовое представление будет правильно отображать исходный текст, но обновления по-прежнему не будут применены.Этот метод вызывается InputMethodService и может также вызываться пользовательскими методами ввода.

@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (request == null)
        return null;

    if ((flags & GET_EXTRACTED_TEXT_MONITOR) != 0)
        mExtractedTextRequest = request;  // mExtractedTextRequest currently doing nothing

    Editable editable = getEditable();
    if (editable == null) {
        return null;
    }
    int selStart = Selection.getSelectionStart(editable);
    int selEnd = Selection.getSelectionEnd(editable);

    ExtractedText extract = new ExtractedText();
    extract.flags = 0;
    extract.partialStartOffset = -1;
    extract.partialEndOffset = -1;
    extract.selectionStart = selStart;
    extract.selectionEnd = selEnd;
    extract.startOffset = 0;
    if ((request.flags & GET_TEXT_WITH_STYLES) != 0) {
        extract.text = new SpannableString(editable);
    } else {
        extract.text = editable.toString();
    }
    return extract;
}

Я добавил более универсальный MCVE здесь .

1 Ответ

0 голосов
/ 23 июня 2018

Ключом к обновлению извлеченного текстового представления является установка токена ExtractedTextRequest.Без токена обновления не вступают в силу.Спасибо за этот ответ за помощь с токеном.

Мы можем токен во входном соединении getExtractedText() с request.token и затем добавить метод в пользовательское представление, чтобы установить его:

@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (request == null)
        return null;

    Editable editable = getEditable();
    if (editable == null) {
        return null;
    }

    // passing the token to the custom view here
    mMongolEditText.setExtractedTextToken(request.token);

    int selStart = Selection.getSelectionStart(editable);
    int selEnd = Selection.getSelectionEnd(editable);

    ExtractedText extract = new ExtractedText();
    extract.flags = 0;
    extract.partialStartOffset = -1;
    extract.partialEndOffset = -1;
    extract.selectionStart = selStart;
    extract.selectionEnd = selEnd;
    extract.startOffset = 0;
    if ((request.flags & GET_TEXT_WITH_STYLES) != 0) {
        extract.text = new SpannableString(editable);
    } else {
        extract.text = editable.toString();
    }
    return extract;
}

Это позволяет мне использовать токен, когда я звоню InputMethodManager.updateExtractedText() из моего собственного представления.

private int mExtractedTextRequestToken = 0;

void setExtractedTextToken(int token) {
    mExtractedTextRequestToken = token;
}

private void reportExtractedText() {

    int requestToken = mExtractedTextRequestToken;

    ExtractedText et = new ExtractedText();
    final CharSequence content = getText();
    final int length = content.length();
    et.partialStartOffset = -1;
    et.partialEndOffset = -1;
    et.startOffset = 0;
    et.selectionStart = getSelectionStart();
    et.selectionEnd = getSelectionEnd();
    et.flags = 0;
    et.text = content.subSequence(0, length);

    InputMethodManager imm = (InputMethodManager) getContext()
            .getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm == null) return;
    imm.updateExtractedText(this, requestToken, et);
}

Вы можете просмотреть мой полный код здесь:

...