TextView
Android Development
HTML formatted text
XML Resources
Android UI Design

Set TextView text from html-formatted string resource in XML

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Android string resources can include lightweight HTML-style markup for emphasis, links, and simple formatting. The correct flow is to keep markup in strings.xml, parse it to a spanned value in code, and assign that to TextView. This keeps localization manageable while still delivering formatted UI text.

Define HTML in strings.xml

Store minimal, supported tags in string resources. Use CDATA for readability.

xml
1<string name="legal_notice"><![CDATA[
2By continuing, you agree to the <b>Terms of Service</b>
3and <a href="https://example.com/privacy">Privacy Policy</a>.
4]]></string>

Keep markup simple. Deeply nested tags are hard for translators and easier to break.

Parse HTML with HtmlCompat

Do not assign raw HTML directly. Parse first:

kotlin
1import androidx.core.text.HtmlCompat
2
3val raw = getString(R.string.legal_notice)
4val spanned = HtmlCompat.fromHtml(raw, HtmlCompat.FROM_HTML_MODE_LEGACY)
5textView.text = spanned

This converts supported HTML tags into Android spans.

If resource includes anchor tags, enable movement method.

kotlin
1import android.text.method.LinkMovementMethod
2
3textView.text = spanned
4textView.movementMethod = LinkMovementMethod.getInstance()
5textView.linksClickable = true

Without movement method, links may appear styled but not respond to taps.

Interpolate Dynamic Values Safely

If you insert runtime values into HTML templates, escape user data first so markup is not corrupted.

kotlin
1import android.text.TextUtils
2import androidx.core.text.HtmlCompat
3
4val template = getString(R.string.welcome_html) // contains %1$s
5val safeName = TextUtils.htmlEncode(userName)
6val raw = String.format(template, safeName)
7textView.text = HtmlCompat.fromHtml(raw, HtmlCompat.FROM_HTML_MODE_LEGACY)

This prevents accidental broken tags from characters in user-provided names.

Theme and Accessibility Considerations

Inline hardcoded colors in HTML can fail in dark mode. Prefer theme-driven styling where possible. If legal or marketing copy needs specific emphasis color, verify contrast in both light and dark themes.

Also test dynamic type and larger font sizes. Long spanned text can wrap differently than plain text and expose layout issues in constrained containers.

Performance in RecyclerView and Repeated Rendering

HTML parsing is relatively cheap for short strings but can still be noticeable when repeated in fast scrolling lists. For repeated content:

  • Parse once and cache spanned text in view model or adapter data.
  • Avoid reparsing in every bind call.
kotlin
1data class RowModel(
2    val id: String,
3    val titleSpanned: CharSequence
4)

Precomputing spans improves rendering consistency in list-heavy screens.

When to Prefer Native Spans Instead of HTML

For complex formatting rules, native span builders can be safer than HTML strings because they avoid translator-facing tag syntax.

kotlin
val text = SpannableString("Terms of Service")
// apply style spans in code if formatting rules are dynamic

Use resource HTML for simple emphasis and links. Use native spans when formatting depends on runtime state, feature flags, or theme logic that is difficult to express in static markup.

Test Strategy

Keep small UI checks for critical formatted strings:

  1. Verify text content is displayed.
  2. Verify expected span types exist.
  3. Verify link clickability.
  4. Verify localization variants do not break tags.

Basic instrumentation assertion example:

kotlin
assert(textView.text.toString().contains("Terms of Service"))

Pair this with screenshot checks for high-risk legal or onboarding text.

Common Pitfalls

  • Assigning raw HTML string directly to TextView without parsing.
  • Expecting full web HTML and CSS behavior in Android text rendering.
  • Forgetting movement method for link interactivity.
  • Inserting unescaped dynamic values into HTML templates.
  • Using hardcoded inline colors that break dark-mode readability.

Summary

  • Store simple HTML markup in string resources for localized formatted text.
  • Parse with HtmlCompat.fromHtml before assigning to TextView.
  • Enable link movement method when strings contain anchors.
  • Escape runtime values before formatting HTML templates.
  • Cache parsed spans in performance-sensitive list rendering paths.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.