Combining Spannable with String.format()

Maarten picture Maarten · Jan 5, 2014 · Viewed 10.4k times · Source

Suppose you have the following string:

String s = "The cold hand reaches for the %1$s %2$s Ellesse's";
String old = "old"; 
String tan = "tan"; 
String formatted = String.format(s,old,tan); //"The cold hand reaches for the old tan Ellesse's"

Suppose you want to end up with this string, but also have a particular Span set for any word replaced by String.format.

For instance, we also want to do the following:

Spannable spannable = new SpannableString(formatted);
spannable.setSpan(new StrikethroughSpan(), oldStart, oldStart+old.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(Color.BLUE), tanStart, tanStart+tan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Is there a robust way of getting to know the start indices of old and tan?

Note that just searching for 'old' returns the 'old' in 'cold', so that won't work.

What will work, I guess, is searching for %[0-9]$s beforehand, and calculating the offsets to account for the replacements in String.format. This seems like a headache though, I suspect there might be a method like String.format that is more informative about the specifics of its formatting. Well, is there?

Answer

George Steel picture George Steel · Nov 30, 2014

I have created a version of String.format that works with spannables. Download it and use it just like the normal version. In your case you would put the spans around the format specifiers (possibly using strings.xml). In the output, they would be around whatever those specifiers were replaced with.