本文介绍了如何在自定义编辑器视图中更新提取的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为垂直的蒙古文字创建了一个自定义编辑器.带圆圈的视图显示了我的自定义编辑器.它们底部的键盘是系统键盘.

I've created a custom editor for vertical Mongolian text. The circled views show my my custom editor. They keyboards at the bottom are system keyboards.

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

When a system keyboard inputs text into it in landscape orientation, though, the keyboard will likely show an extracted text view rather than my custom editor view. The circled view below is the extracted text view (which is not getting updated by my custom editor).

我需要以某种方式将更新从我的视图发送到输入法管理器. InputConnection文档:

I need to somehow send updates from my view to the input method manager. This is stated in the InputConnection documentation:

我一直在探索与提取文本有关的源代码

I've been exploring the source code related to extracted text

  • TextView
  • Editor
  • InputMethodManager
  • InputMethodService
  • BaseInputConnection

但我迷路了.

这是我最近得到的.这是我的自定义编辑器中的一种方法.

Here is the closest I've gotten. This is a method inside my custom editor.

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的引用,该引用应用于修改提取的文本更新中包含的内容.

When I am inside my editor I don't have a reference to the ExtractedTextRequest, which should be used to modify what I include in my extracted text update.

这是我的BaseInputConnection子类内的另一种方法(从此处).我可以访问ExtractedTextRequest,但这不是我从中调用更新的地方.这将导致提取的文本视图正确显示初始文本,但仍然无法应用更新.此方法由InputMethodService调用,也可以由自定义输入方法调用.

Here is another method inside my BaseInputConnection subclass (slightly modified from here). I have access to the ExtractedTextRequest but this is not where I am calling the updates from. It will cause the extracted text view to show the initial text correctly, but the updates still don't get applied. This method is called by the InputMethodService and can also be called by custom input methods.

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

I added a more generic MCVE here.

推荐答案

更新提取的文本视图的关键是设置ExtractedTextRequest令牌.没有令牌,更新将不会生效.感谢此答案以获取有关令牌的帮助.

The key to updating the extracted text view is to set the ExtractedTextRequest token. Without the token the updates don't take effect. Thanks to this answer for help with the token.

我们可以使用request.token在输入连接的getExtractedText()中标记令牌,然后将方法添加到自定义视图中进行设置:

We can the token in the input connection's getExtractedText() with request.token and then add a method to the custom view to set it:

@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()时使用令牌.

That allows me to use the token when I call InputMethodManager.updateExtractedText() from within my custom view.

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

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

You can view my full code here:

  • Custom view
  • Input connection

这篇关于如何在自定义编辑器视图中更新提取的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 20:00