如何在自定义编辑器视图中更新提取的文本

时间:2018-06-13 05:02:34

标签: android textview android-custom-view android-input-method android-extracted-text

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

enter image description here

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

enter image description here

我需要以某种方式将更新从我的视图发送到输入方法管理器。这在InputConnection documentation

中说明
  

编辑作者:作为一般规则,尝试遵守中的字段   请求返回多少个字符,但是如果性能或   为方便起见,请随意做最多的事情   适合您的情况。另外,如果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子类中的另一种方法(稍微修改自here)。我可以访问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 here

1 个答案:

答案 0 :(得分:0)

更新提取的文本视图的关键是设置ExtractedTextRequest令牌。没有令牌,更新将不会生效。感谢this answer为令牌提供的帮助。

我们可以使用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);
}

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