Skip to content

Instantly share code, notes, and snippets.

@DDihanov
Last active July 2, 2021 07:29
Show Gist options
  • Save DDihanov/ec81d612e58f925366a2daae66a4977d to your computer and use it in GitHub Desktop.
Save DDihanov/ec81d612e58f925366a2daae66a4977d to your computer and use it in GitHub Desktop.
Formats URLSpans with a %s placeholder into new URLSpans with vararg URLs
// usage:
// spannedStringFormatter.format(context.getText(R.string.mystring), "url1", "url2"))
// where R.string.mystring is <string name="mystring"><![CDATA[ Link one <a href="%s"><b> Link one</b></a> and link two <a href="%s"><b>Link two</b></a>.]]></string>
class SpannedStringFormatter {
/**
* replace all the %s in the spanned string with corresponding URLs
*/
fun format(format: CharSequence, vararg urls: String?): SpannedString {
// make a spannable copy so that we can change the spans (Spanned is immutable)
val spannableString = SpannableStringBuilder(String.format(format.toString(), *urls).toHtmlSpan())
val oldUrlSpans = spannableString.getSpans(
0, spannableString.length,
URLSpan::class.java
)
oldUrlSpans.forEachIndexed { index, urlSpan ->
// get the span range
val start = spannableString.getSpanStart(urlSpan)
val end = spannableString.getSpanEnd(urlSpan)
// remove the old span
spannableString.removeSpan(urlSpan)
// add the new url span in the same place
val underlineSpan = URLSpan(urls[index])
spannableString.setSpan(underlineSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
return SpannedString(spannableString)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment