I used to think that TextViews were pretty plain; they contained a CharSequence, and that was it. But it can actually contain a Spanned (or its mutable cousin, Spannable) buffer type as well. This means that there are a host of HTML tags that you can use to modify your TextView, which allows for different typefaces/functionality - all in the same TextView. Check out what you can do with just one string resource in a TextView:
Here's the string resource for above:
<string name="html">This <b>is</b> <i>all</i> <sub>in</sub> <u><sup>one</sup></u> <a href="http://google.com">TextView</a>.</string>
Android has tips on the basics of Html in TextViews, but it doesn't nearly cover some of the use cases. It also doesn't have a reference on which tags are supported (scroll to bottom for a reference I created).
Here are a few tips:
Links in TextViews
The simplest way to add links to TextView is to use the android:autoLink attribute. However, this only allows you to link visible URIs in the text and can sometimes lead to undesired situations (I had an app that was detecting the copyright dates "2009-2011" as a phone number). By using the <a> tag, you can create links with any text that leads to any URI:
<string name="my_site"><a href="http://idunnolol.com">My Website</a></string>
There's only one catch: when you try to use this in a TextView, it won't be clickable unless you set the movement method in code:
TextView myTextView = (TextView) findViewById(R.id.my_textview);
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
Dynamic Html
All of the above examples have been with static text - that is, when the TextView's android:text attribute is set in XML from a string resource. What if you want to set a TextView's string resource in code? This is especially important when you use string formatting (which I'm a big fan of).
Android discusses this already, but for posterity I'll repeat the process here:
1. HTML-escape the string resource:
<string name="loud">Loud text here: <b>%s</b></string>
2. Use Html.fromHtml() to dynamically create a Spanned that a TextView can be styled with:
Spanned spanned = Html.fromHtml(context.getString(R.string.loud, "this is loud"));
myTextView.setText(spanned);
Handling Custom Tags
So far so good, but I ran into a problem the other day: while the <strike> tag works if it's linked as a static string, it doesn't work when using Html.fromHtml(). I looked through the source code and discovered that Html.fromHtml() handles a different set of tags from static resources. Luckily, there's a way to handle tags that Html.fromHtml() doesn't: the TagHandler interface.
It's a little complex, but here's one possible solution for how to handle the <strike> tag. (My own solution differed a bit, but the essentials are the same.)
Tags Supported in String Resources
Tags in static string resources are parsed by android.content.res.StringBlock, which is a hidden class. I've looked through the class and determined which tags are supported:
- <a> (supports attributes "href")
- <annotation>
- <b>
- <big>
- <font> (supports attributes "height", "size", "fgcolor" and "bicolor", as integers)
- <i>
- <li>
- <marquee>
- <small>
- <strike>
- <sub>
- <sup>
- <tt>
- <u>
Tags Supported by Html.fromHtml()
For some reason, Html.fromHtml() handles a different set of of tags than static text supports. Here's a list of the tags (gleaned from Html.java's source code):
- <a> (supports attribute "href")
- <b>
- <big>
- <blockquote>
- <br>
- <cite>
- <dfn>
- <div>
- <em>
- <font> (supports attributes "color" and "face")
- <i>
- <img> (supports attribute "src". Note: you have to include an ImageGetter to handle retrieving a Drawable for this tag)
- <p>
- <small>
- <strong>
- <sub>
- <sup>
- <tt>
- <u>
The font "color" attribute supports some color names (along with the normal integer-based color scheme):
- aqua
- black
- blue
- fuchsia
- green
- grey
- lime
- maroon
- navy
- olive
- purple
- red
- silver
- teal
- white
- yellow
Awesome - thanks very much.
ReplyDeleteIs this true for all SDK levels?
Very nice, and very Blackberry of you :)
ReplyDeleteIt's the way I have handled html content from RSS feeds for Blackberry -- easier than implementing an entire WebView (BrowserField in BB)
@Mark: As far as I can tell from the git repo, it appears this is true for all SDK levels. It doesn't look like they ever added or removed tags, but I just skimmed so I might be a bit off.
ReplyDeleteSo size is only supported by static string right? Why is that so?
ReplyDeleteGreat
ReplyDeleteI get a "android.view.InflateException: Binary XML file line #9: Error inflating class " when I try to add a string with html to my textview in layout xml.
ReplyDeleteIn strings.xml, this is what I have.
<font size="20px">Some heading!</font> some text blah blah blah.
I think I'm going to need to see more of the stack trace to understand what's going wrong.
Delete20px, px, px, are you sure?
Deletei got problem wen show html on text view in case html code contain style tag and inside style tag we have some commented code.then after using Html.fromHtml() the commented code is also show but i do't require it.
ReplyDeleteHi I am beginner in android. but I have written some C code which is formatted in HTML using some style like font-color. I tried to display in TextView, it works fine but font color displayed only in black color.
ReplyDeletehelp me from this problem by writing an example. thank you in advanced.
What all attributes are supported in the div tag ?
ReplyDeleteThis is Very very nice article. Everyone should read. Thanks for sharing. Don't miss WORLD'S BEST
ReplyDeleteDus Bahane 2.0 Full Video Song From BAAGHI 3 (Tiger Shroff, Shraddha Kapoor) Dus Bahane Karke Le Gaye Dil