1

我为垂直蒙古语文本创建了一个自定义编辑器。带圆圈的视图显示了我的自定义编辑器。底部的键盘是系统键盘。

在此处输入图像描述

但是,当系统键盘以横向输入文本时,键盘可能会显示提取的文本视图,而不是我的自定义编辑器视图。下面带圆圈的视图是提取的文本视图(我的自定义编辑器没有更新)。

在此处输入图像描述

我需要以某种方式将更新从我的视图发送到输入法管理器。这在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,它应该用于修改我在提取的文本更新中包含的内容。

这是我的子类中的另一种方法(从此处BaseInputConnection稍作修改)。我可以访问,但这不是我调用更新的地方。这将导致提取的文本视图正确显示初始文本,但更新仍然没有得到应用。该方法由 调用,也可以由自定义输入法调用。ExtractedTextRequestInputMethodService

@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 。

4

1 回答 1

0

更新提取的文本视图的关键是设置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);
}

你可以在这里查看我的完整代码:

于 2018-06-23T01:43:35.453 回答