Html in TextViews
Using HTML in TextViews can be helpful for formatting, especially when displaying content retrieved from a server. For optimal layout and control a custom native layout – either XML or programmatic is preferred, however using HTML in a TextView can give you results quick, while still maintaining a native app feel and look. Here’s everything you need to know.
To display HTML in a TextView, use the android.text.Html
class. This creates a Spanned object that the TextView can display.
val html = """Hello <font color="#ed6b61">World</font>""" textView.text = Html.fromHtml(html)
What is supported
These tags are supported with android.text.Html
font | em | tt | h1 |
p | cite | a | h2 |
ul | dfn | u | h3 |
li | i | del | h4 |
div | big | s | h5 |
span | small | strike | h6 |
strong | font | sup | img |
b | blockquote | sub | br |
Customization
If the out-of-the-box support for HTML does not meet you needs, Android allows customization – with limitations. When constructing the string from HTML we can supply a TagHandler
.
class MyTagHandler : TagHandler { override fun handleTag(opening: Boolean, tag: String, output: Editable, xmlReader: XMLReader) { //do formatting/styling here } }
And then pass an instance to the `Html.fromHtml` method
textView.setText(Html.fromHtml(html, null, MyTagHandler()))
TagHandler
is only given the tags that system does not support – which can vary depending on the version of Android.The warning above is important! TagHandler is limited only to tags that the version of Android your user is running supports. Want to use lists or ordered lists? It is supported in Android N and above – but it might not be the way you want it. Unfortunately there is not a means to override the default behavior. If you are determined to use HTML your best bet – as far as I am aware – is to use a custom tag, and then implement it in a TagHandler
.
Thankfully, there is a 3rd party library that allows overriding ALL tags. See below for details.
Third Party Support
There is one maintained 3rd party lib I’ve found with some decent HTML support that goes beyond the built-in TextView. HtmlSpanner has support for more tags and is extensible. It allows you to override ALL tags, so you can customize any tag.
With HtmlSpanner handle tags as shown below:
class HtmlTagNodeHandler(val wrappedHandler: TagNodeHandler) : TagNodeHandler() { override fun handleTagNode(node: TagNode?, builder: SpannableStringBuilder?, start: Int, end: Int, spanStack: SpanStack?) { //override any tag here - must register for each tag } }
val htmlSpanner = HtmlSpanner() htmlSpanner.registerHandler("font", FontHandler()) textView.setText(htmlSpanner.fromHtml(html))
Closing Thoughts
TextView can be used with HTML, however is limited in its support. If your looking into HTML support, you probably have a bigger question of how can we share code/layout across platforms. Implementing layouts 3+ times (Android, iOS, Web) is a lot of work and anyway to DRY it up is a big savings. That’s what makes solutions like Flutter so appealing. Using HTML in TextViews may be a partial solution for sharing some content/formatting.