0

I'm battling a bit with an issue. I have an app that writes some formatted text in an EditText view. It does that through a 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;

        }
    }

whether I use (1), (2), (3), (4), I get the expected corresponding decoration in the EditText, so "the Spans are working" as far as the EditText is concerned.

On the other side of the fence, I have an InputMethod accessing this text content via getCurrentInputConnection().getExtractedText(...) as in :

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

    } 

Now, still from the InputMethod perspective, I want to retrieve the spans in the extracted text. Which I do through something like that :

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

My problem is that the ImageSpan spans from (1) are NOT part of those span array (be it spans or rawSpans), and therefore I cannot detect those particular spans, and cannot do further processing. If however I use (2) (3) or (4), those are part of those span arrays, as expected. What's so special about that ImageSpan that it totally bypasses the extracted text ?

Thanks for your time!

0xAFEB
  • 11
  • 1
  • I would have to browse the sources of the OS to confirm, but it's probably the part that renders the ImageSpan that also calls removeSpan once done. – 0xAFEB Aug 28 '14 at 23:11

1 Answers1

0

The answer is in 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]);
    }
}

This is why they don't make it to the IME, they're consumed and removed along the way.

0xAFEB
  • 11
  • 1