22

I am working in a wiki-like parser that creates spans for a set of markup tokens. It is working, but inside the token iterator I frequently need to convert the partial results on a SpannableStringBuilder to a SpannableString. This is called pretty frequently, so I'm after the most efficient solution to do it, and avoid creating extra objects.

At the moment I'm using;

SpannableStringBuilder stuff=complex_routine_that_builds_it();
SpannableString result=SpannableString.valueOf(stuff);

However this valueOf call internally builds a SpannableString kind of from scratch, doing a toString and a loop to copy assigned spans.

As SpannableStringBuilder name suggests, I think that maybe there's a quicker way to get the SpannableString from the builder. Is it true?

rupps
  • 9,183
  • 4
  • 53
  • 87
  • if you have some spans in your text all you need is android.text.Spanned – pskink Apr 20 '14 at 09:01
  • 2
    yes I understand it now, the name `SpannableStringBuilder` confused me, I am used to working with `StringBuffer` then getting a `String` at the end, and didn't realized that `SpannableStringBuilder` also implements `Spanned`, `Charsequence`, etc ... The builder comes in handy to me because the parser does a lot of operations on incoming strings to remove markup and create many different spans: URL, colors, sizes, ... Basically I'm rewriting the (terribly) slow `Html.fromHtml` – rupps Apr 20 '14 at 09:11
  • 2
    great idea, i dont know why but 95% of mates here use fromHtml, even if input is not html : they first build artificial html and then call fromHtml, i cannot find more stupid thing – pskink Apr 20 '14 at 09:21
  • 1
    yesss and if you look at the Html.java source code you just want to die... it parses the string into a XML SaxParser (!), then uses a 100kb library Tagsoup with zillions of regular expressions that check for well-formedness, XML Schemas and whatnot.... only to support just bold, italic, headers and colors, something I've done with roughly 150 lines and is 10 times faster! – rupps Apr 20 '14 at 09:27

1 Answers1

35

There is no need to convert a SpannableStringBuilder to a SpannableString when you can use it directly, as in a TextView:

SpannableStringBuilder stuff = complex_routine_that_builds_it();
textView.setText(stuff);

As the question already showed, you could make the conversion if you absolutely had to by

SpannableStringBuilder stuff = complex_routine_that_builds_it();
SpannableString result = SpannableString.valueOf(stuff);

but you should consider why you would even need to make that conversion? Just use the original SpannableStringBuilder.

SpannableString vs SpannableStringBuilder

The difference between these two is similar to the difference between String and StringBuilder. A String is immutable but you can change the text in a StringBuilder.

Similarly, the text in a SpannableString is immutable while the text in a SpannableStringBuilder is changeable. It is important to note, though, that this only applies to the text. The spans on both of them (even a SpannableString) can be changed.

Related

Community
  • 1
  • 1
Suragch
  • 364,799
  • 232
  • 1,155
  • 1,198