Html

Set TextView text from html-formatted string resource in XML

25 September 2026 · 7 min read

Set TextView text from html-formatted string resource in XML

Crafting engaging and visually appealing user interfaces in Android often goes beyond simple plain text. Developers frequently need to display rich, formatted content within a TextView, incorporating elements like bolding, italics, links, and even different colors. While directly embedding complex formatting in code can become cumbersome and hard to maintain, Android provides a robust solution: you can Set TextView text from html-formatted string resource in XML. This approach streamlines localization, enhances readability, and allows for dynamic content updates without recompiling your application. Understanding how to correctly leverage XML string resources for rich text is a fundamental skill for any Android developer aiming to deliver a superior user experience.

The Power of Rich Text and Android String Resources

In modern application development, plain text often falls short when conveying information effectively. Imagine an app displaying a legal disclaimer, a product description, or even a simple welcome message; adding emphasis through bolding, structuring information with paragraphs, or highlighting key terms can significantly improve clarity and user engagement. Android’s TextView is incredibly versatile, capable of rendering more than just unformatted characters. By externalizing your text content into string resources, you not only prepare your application for easy localization but also gain a powerful mechanism for injecting rich text formatting directly from your XML files.

String resources in Android are stored in res/values/strings.xml, centralizing all your text content. This separation of concerns is a core principle of good software design, making your app easier to manage, update, and translate into multiple languages. When you need to apply specific styling—like making a word bold or italic—directly within these strings, traditional methods of escaping characters can quickly become unwieldy. This is where rich text capabilities become invaluable, allowing you to embed standard HTML tags within your string resources, which the TextView can then interpret and render appropriately. This method ensures that your UI remains dynamic and visually appealing, adapting to various content needs.

Embedding HTML Directly in XML String Resources with CDATA

To effectively set TextView text from html-formatted string resource in XML, you’ll primarily use standard HTML tags within your strings.xml file. However, XML parsers can be particular about characters like < and >, which are integral to HTML. Directly writing <b>Important</b> might lead to parsing errors because the XML parser interprets <b> as an XML tag, not part of a string value. The solution lies in using a CDATA section.

A CDATA (Character Data) section is used to tell the XML parser to treat the content within it as plain character data, ignoring any special XML characters. This allows you to embed raw HTML markup without needing to escape every single angle bracket or ampersand. For example, instead of writing <string name="my_html_text">&lt;b&gt;Hello&lt;/b&gt;</string>, you can simply wrap your HTML within <![CDATA[...]]>. This significantly improves readability and reduces the chances of syntax errors.

Here’s a practical example of how to define an HTML-formatted string resource using a CDATA block in your strings.xml file:

<resources> <string name="welcome_message"><![CDATA[<p>Welcome to our <b>amazing</b> app!</p><p>Click <a href="https://example.com/learn-more">here</a> to learn more.</p>]]></string> </resources> 

This method keeps your HTML concise and easy to manage within the XML structure, ensuring that your rich text content is neatly contained and accessible for your Android application.

Infographic: Steps to Display HTML in TextView
Programmatic Parsing: Bridging XML to TextView ----------------------------------------------

Once you’ve defined your HTML-formatted string resource in XML, the next step is to retrieve it in your Android code and correctly render it within a TextView. Simply setting the string resource directly to a TextView using setText() will display the raw HTML tags. To parse and render the HTML, you need to convert it into a Spanned object, which the TextView understands as rich text. This is where the HtmlCompat class from AndroidX becomes essential.

The HtmlCompat.fromHtml() method is specifically designed for this purpose. It takes your HTML string and converts it into a Spanned object, preserving the formatting. This method also handles different API levels gracefully, ensuring compatibility across various Android versions. For example, older versions of Android might not fully support all HTML tags or attributes, and HtmlCompat helps bridge these differences, providing a more consistent rendering experience across devices.

Here’s how you would typically retrieve and display the HTML-formatted string in your Kotlin or Java code:

  1. Retrieve the string resource: Use getString(R.string.your_string_name) to get the HTML string from your strings.xml.
  2. Parse the HTML: Call HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_LEGACY). The FROM_HTML_MODE_LEGACY flag is often used for broader compatibility, though other modes exist for more specific parsing needs.
  3. Set to TextView: Assign the resulting Spanned object to your TextView using setText(spannedObject).
// Kotlin example val welcomeMessageHtml = getString(R.string.welcome_message) val spannedText = HtmlCompat.fromHtml(welcomeMessageHtml, HtmlCompat.FROM_HTML_MODE_LEGACY) findViewById<TextView>(R.id.myTextView).text = spannedText // Java example String welcomeMessageHtml = getString(R.string.welcome_message); Spanned spannedText = HtmlCompat.fromHtml(welcomeMessageHtml, HtmlCompat.FROM_HTML_MODE_LEGACY); ((TextView) findViewById(R.id.myTextView)).setText(spannedText); 

For handling links within the HTML, you might also need to set android:autoLink="web" in your XML layout for the TextView or programmatically use myTextView.movementMethod = LinkMovementMethod.getInstance(). This ensures that clickable links embedded in your HTML are recognized and actionable by the user.

According to the official Android Developers documentation on Styled text resources, this method is the recommended way to handle styled text, offering flexibility and robustness. This approach ensures that your content is both visually appealing and maintainable.

Best Practices and Advanced Considerations for Rich Text

When you set TextView text from html-formatted string resource in XML, there are several best practices and advanced considerations to ensure your application performs optimally and remains secure. While HtmlCompat.fromHtml() is powerful, it has limitations regarding the full spectrum of HTML and CSS. It supports a subset of common tags like <b>, <i>, Question & Answer :

I have some fixed strings inside my strings.xml, something like:

<resources> <string name="somestring"> <B>Title</B><BR/> Content </string> </resources> 

and in my layout I’ve got a TextView which I’d like to fill with the html-formatted string.

<TextView android:id="@+id/formattedtext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/htmlstring"/> 

if I do this, the content of formattedtext is just the content of somestring stripped of any html tags and thus unformatted.

I know that it is possible to set the formatted text programmatically with

.setText(Html.fromHtml(somestring));

because I use this in other parts of my program where it is working as expected.

To call this function I need an Activity, but at the moment my layout is just a simple more or less static view in plain XML and I’d prefer to leave it that way, to save me from the overhead of creating an Activity just to set some text.

Am I overlooking something obvious? Is it not possible at all? Any help or workarounds welcome!

Edit: Just tried some things and it seems that HTML formatting in xml has some restraints:

  • tags must be written lowercase
  • some tags which are mentioned here do not work, e.g. <br/> (it’s possible to use \n instead)

Just in case anybody finds this, there’s a nicer alternative that’s not documented (I tripped over it after searching for hours, and finally found it in the bug list for the Android SDK itself). You CAN include raw HTML in strings.xml, as long as you wrap it in

<![CDATA[ ...raw html... ]]> 

Edge Cases:

  • Characters like apostrophe (’), double-quote ("), and ampersand (&) only need to be escaped if you want them to appear in the rendered text AS themselves, but they COULD be plausibly interpreted as HTML.
    • ' and " can be represented as\' and \", or &apos; and &quot;.
    • < and > always need to be escaped as &lt; and &gt; if you literally want them to render as ‘<’ and ‘>’ in the text.
    • Ampersand (&) is a little more complicated.
      • Ampersand followed by whitespace renders as ampersand.
      • Ampersand followed by one or more characters that don’t form a valid HTML entity code render as Ampersand followed by those characters. So… &qqq; renders as &qqq;, but &lt;1 renders as <1.

Example:

<string name="nice_html"> <![CDATA[ <p>This is a html-formatted \"string\" with <b>bold</b> and <i>italic</i> text</p> <p>This is another paragraph from the same \'string\'.</p> <p>To be clear, 0 &lt; 1, & 10 &gt; 1<p> ]]> </string> 

Then, in your code:

TextView foo = (TextView)findViewById(R.id.foo); foo.setText(Html.fromHtml(getString(R.string.nice_html), FROM_HTML_MODE_LEGACY)); 

IMHO, this is several orders of magnitude nicer to work with :-)


August 2021 update: My original answer used Html.fromHtml(String), which was deprecated in API 24. The alternative fromHtml(String,int) form is suggested as its replacement.

FROM_HTML_MODE_LEGACY is likely to work… but one of the other flags might be a better choice for what you want to do.

On a final note, if you’d prefer to render Android Spanned text suitable for use in a TextView using Markdown syntax instead of HTML, there are now multiple thirdparty libraries to make it easy including https://noties.io/Markwon.