【问题标题】:ImageSpans are not retrieved through inputconnection / getExtractedTextImageSpan 不通过 inputconnection / getExtractedText 检索
【发布时间】:2014-10-20 20:52:43
【问题描述】:

我正在与一个问题作斗争。 我有一个在 EditText 视图中写入一些格式化文本的应用程序。 它通过 StyleableSpannableStringBuilder 来实现:

    public class StyleableSpannableStringBuilder extends SpannableStringBuilder
    {
        public StyleableSpannableStringBuilder appendMarkup(CharSequence text, Context context, int resID)
        {
            super.append(text);
            int startPos = length() - text.length();

            ImageSpan kwSpan = new ImageSpan(context, resID, ImageSpan.ALIGN_BASELINE); //(1)
            //BackgroundColorSpan kwSpan = new BackgroundColorSpan(Color.RED); //(2)
            //BulletSpan kwSpan = new BulletSpan(5, Color.RED); //(3)
            //StyleSpan kwSpan = new StyleSpan(Typeface.BOLD_ITALIC); //(4)

            setSpan(kwSpan, startPos, length(), SPAN_EXCLUSIVE_EXCLUSIVE);
            return this;

        }
    }

无论我使用 (1)、(2)、(3)、(4),我都会在 EditText 中得到预期的相应装饰,因此就 EditText 而言,“跨度正在工作”。

在栅栏的另一边,我有一个 InputMethod,它通过 getCurrentInputConnection().getExtractedText(...) 访问此文本内容,如下所示:

    InputConnection ic = getCurrentInputConnection();
    if (ic != null)
    {
        ExtractedTextRequest req = new ExtractedTextRequest();
        req.token = mExtractedTextToken;

        req.hintMaxChars = MAX_REQUEST_CHARS;
        req.flags = InputConnection.GET_TEXT_WITH_STYLES;
        mExtractedText = ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR );

    } 

现在,仍然从 InputMethod 的角度来看,我想检索提取文本中的跨度。我通过类似的方式做到了:

            CharacterStyle[ ] spans = mCurrentText.getSpans(0, mCurrentText.length(), CharacterStyle.class);
            Object[] rawSpans = mCurrentText.getSpans(0, mCurrentText.length(), Object.class);
            Log.e(TAG,"rawSpans :" + rawSpans.length + " / Spans : " + spans.length);

我的问题是(1)中的 ImageSpan 跨度不是这些跨度数组的一部分(无论是跨度还是 rawSpan),因此我无法检测到那些特定的跨度,也无法进行进一步处理。但是,如果我使用 (2) (3) 或 (4),则它们是那些跨度数组的一部分,正如预期的那样。 ImageSpan 有什么特别之处,它完全绕过了提取的文本?

感谢您的宝贵时间!

【问题讨论】:

  • 我必须浏览操作系统的源代码才能确认,但它可能是渲染 ImageSpan 的部分,一旦完成,它也会调用 removeSpan。

标签: android android-edittext android-input-method spannablestring


【解决方案1】:

答案在TextView.java

/**
* This is used to remove all style-impacting spans from text before new
* extracted text is being replaced into it, so that we don't have any
* lingering spans applied during the replace.
*/
static void removeParcelableSpans(Spannable spannable, int start, int end) {
    Object[] spans = spannable.getSpans(start, end, ParcelableSpan.class);
    int i = spans.length;
    while (i > 0) {
        i--;
        spannable.removeSpan(spans[i]);
    }
}

这就是为什么它们没有进入 IME,它们在此过程中被消耗和删除。

【讨论】:

    猜你喜欢
    • 2011-12-28
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2013-04-14
    相关资源
    最近更新 更多