Search code examples
javaandroidandroid-typefacespannablestringbuilder

Can multiple setSpan be applied to the same SpannableStringBuilder?


I have a list of specific words from a sentence that I would like to bold and change the text color for. For some reason the text color change is working, but the bold does not seem to be applied. What's more weird is that changing the typeface to Italic reflects. My question is, what could be causing my text not to bold?

// lets create a list of words
ArrayList<String> alWords = new ArrayList<>();
alWords.add("Mary");
alWords.add("lamb");

// had earlier StringBuilder to form 'Mary had a little lamb.' for example
SpannableStringBuilder sentence = new SpannableStringBuilder(sb.toString());

// iterate through list of words and bold & color change text
for (int i = 0; i < alWords.size(); i++) {
   Pattern word = Pattern.compile(alWords.get(i));
   Matcher match = word.matcher(sentence);

   int startPos = 0;
   int endPos = 0;

   while (match.find()) {
      startPos = match.start();
      endPos = match.end();
   }
   sentence.setSpan(new StyleSpan(Typeface.BOLD), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
   sentence.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, R.color.green)), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} 

tvText.setText(sentence, TextView.BufferType.SPANNABLE);

This results in the correct words with the color change, but no bold. If you update to Italic, it all works too. Only bold text does not work. Any thoughts why?

For further examination, here is my dumpSpans logs:

span= Mary: 1c181a6 android.text.style.StyleSpan (0-4) fl=#33 
span= Mary: 148f7e7 android.text.style.ForegroundColorSpan (0-4) fl=#33 
span= lamb: b441f94 android.text.style.StyleSpan (18-22) fl=#33 
span= lamb: e18ba3d android.text.style.ForegroundColorSpan (18-22) fl=#33

Solution

  • Instead of SpannableStringBuilder I use SpannableString and it works fine.
    Try to this code:

    SpannableString sentence = new SpannableString(sb.toString());
    

    and then

    tvText.setText(sentence);