androidspannablestringspanned

How to change one span type to another in Android?


I would like to take all the spans of one type in a CharSequence and convert them to a different type. For example, convert all the bold spans to underline spans:

enter image description here

How would I do that?

(This was a problem I was facing today, and since I have solved it now, I am adding a Q&A pair here. My answer is below.)


Solution

  • How to change spans from one type to another

    enter image description here

    In order change the spans, you need to do the following things

    1. Get all the spans of the desired type by using getSpans()
    2. Find the range of each span with getSpanStart() and getSpanEnd()
    3. Remove the original spans with removeSpan()
    4. Add the new span type with setSpan() in the same locations as the old spans

    Here is the code to do that:

    Spanned boldString = Html.fromHtml("Some <b>text</b> with <b>spans</b> in it.");
    
    // make a spannable copy so that we can change the spans (Spanned is immutable)
    SpannableString spannableString = new SpannableString(boldString);
    
    // get all the spans of type StyleSpan since bold is StyleSpan(Typeface.BOLD)
    StyleSpan[] boldSpans = spannableString.getSpans(0, spannableString.length(), StyleSpan.class);
    
    // loop through each bold span one at a time
    for (StyleSpan boldSpan : boldSpans) {
    
        // get the span range
        int start = spannableString.getSpanStart(boldSpan);
        int end = spannableString.getSpanEnd(boldSpan);
    
        // remove the bold span
        spannableString.removeSpan(boldSpan);
    
        // add an underline span in the same place
        UnderlineSpan underlineSpan = new UnderlineSpan();
        spannableString.setSpan(underlineSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    

    Notes

    See also