用户更改选择时如何将撰写文本提交给 InputConnection

Posted

技术标签:

【中文标题】用户更改选择时如何将撰写文本提交给 InputConnection【英文标题】:How to commit composing text to an InputConnection when the user changes the selection 【发布时间】:2017-12-25 14:26:39 【问题描述】:

我正在制作custom keyboard,并且必须在提交之前设置组合文本。这在this Q&A 中有描述。

我知道如何提交文本

inputConnection.commitText("text", 1);

但是如果用户通过触摸EditText 的另一部分来更改光标位置,我不知道如何提交。通过观察其他键盘,我知道这是可能的,因为他们这样做了。但是在我的键盘上,如果我有

inputConnection.setComposingText("text", 1);

然后改变光标位置,就留下了作曲跨度。未来的任何更改都将替换作曲跨度,而不是在新的光标位置输入。

android EditText listener for cursor position change 帖子提供了一些关于您可以对EditText 做什么的想法,但在自定义键盘中,除了InputConnection 给我的功能之外,我无法访问EditText

我如何知道光标/选择何时移动?

我keep 在我开始写我的问题后找到了答案。我将在下面发布答案。

【问题讨论】:

【参考方案1】:

编辑器(EditText 等)在InputMethodManager 上调用updateSelection,然后通知onUpdateSelection 侦听器。因此,键盘可以覆盖onUpdateSelection 并处理那里未完成的作曲范围。

要处理未完成的作曲跨度,您可以在 InputConnection 上使用 finishComposingText。这将删除组成跨度并提交跨度中的任何文本。

这是sample Android soft keyboard中的实现方式:

/**
 * 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();
        
    

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于用户更改选择时如何将撰写文本提交给 InputConnection的主要内容,如果未能解决你的问题,请参考以下文章

提交时如何更改文本

如何在更改下拉列表时提交表格?

JQuery DatePicker 只读

如何将原始innerHTML 传递给php?

如何避免vue中api调用的onchange?

单选按钮,更改背景颜色 PHP