1

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
forpas
  • 160,666
  • 10
  • 38
  • 76
portfoliobuilder
  • 7,556
  • 14
  • 76
  • 136
  • 1
    i did not have time to test it but what do you see if you use `tvText.setText(Html.fromHtml("this is some bold red text, and here is not"))` ? – pskink Oct 24 '18 at 19:31
  • @pskink that seems to work, although I have to know explicitly the exact words that will be bolded. My example is suppose to represent any String (sentence) that is created with StringBuilder, and then bold and color any one word that could be in various positions. But using Html.fromHtml work fine. Just not applicable for more complex or dynamic bolding – portfoliobuilder Oct 24 '18 at 20:27
  • call TextUtils.dumpSpans with the Spannable returned from HTML.fromHtml and see the spans on the logcat, what do you see? – pskink Oct 24 '18 at 20:30
  • Well, I am unable to achieve the look I want with Html solution. Like I said, this only works for simple scenarios. For example, mixing and matching you cannot use Html solution e.g. "Hello , this is not bold, but I am , the end". To achieve more complicated bolding you have to setSpan with start/end values so that you can bold every other word, or every other letter. It's whatever you want. With Html, its limited to whatever input I add between the tags. – portfoliobuilder Oct 24 '18 at 20:33
  • Html. fromHtml was only test - don't use it - just dumpSpans on the value returned from that methods and post the result – pskink Oct 24 '18 at 20:36
  • 1
    see https://pastebin.com/raw/cmRxyg65 – pskink Oct 24 '18 at 21:01
  • btw why you do `while (match.find()) {` and inside the loop you are not using `startPos` & `endPos` in any way? you should call `setSpan` inside the loop, shouldn't you? – pskink Oct 24 '18 at 21:08
  • @pskink No. The while loop is for getting start and end indexes for the word I am looking for. The for loop handles setting the span for all the words I want to bold/color change. – portfoliobuilder Oct 25 '18 at 00:03
  • ok so it seems i dont understand your code... – pskink Oct 25 '18 at 04:59

1 Answers1

1

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);
forpas
  • 160,666
  • 10
  • 38
  • 76
  • Are they not teh same thing? – Jono Feb 05 '21 at 15:28
  • No, they are 2 different classes: https://developer.android.com/reference/android/text/SpannableStringBuilder and https://developer.android.com/reference/android/text/SpannableString. – forpas Feb 05 '21 at 15:30