How to show an HTML string in an Android TextView

Filed under “What I learned about Android today,” you can display an HTML string in an Android TextView. However, this approach has major limitations, and you’ll probably want to display your HTML in a WebView instead.

Skipping past that for a few moments ... if you want to try to display an HTML string in a TextView, you need to use the Android Html.fromHtml() method, as shown in this code:

// get our html content
String htmlAsString = getString(R.string.html);
Spanned htmlAsSpanned = Html.fromHtml(htmlAsString); // used by TextView

// set the html content on the TextView
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(htmlAsSpanned);

My HTML string

In my example code I’ve defined a String in XML in my res/values/strings.xml file like this:

<resources>
    <string name="app_name">TestProject2</string>

    <string name="html">
        <![CDATA[
        <h1>Main Title</h1>
        <h2>A sub-title</h2>
        <p>This is some html. Look, here\'s an <u>underline</u>.</p>
        <p>Look, this is <em>emphasized.</em> And here\'s some <b>bold</b>.</p>
        <p>This is a UL list:
        <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
        </ul>
        <p>This is an OL list:
        <ol>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
        </ol>
        ]]>
    </string>
</resources>

As shown, if you’re going to put HTML content in a string in an XML file like this, you need to put it inside a CDATA element.

What a TextView looks like

With a layout file defined like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              tools:context=".MainActivity"
              android:orientation="vertical"
              android:gravity="top|fill_vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>

    <!--
    <WebView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/webView"
        android:layout_below="@+id/helloWorld"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        />
    -->

</LinearLayout>

and a MainActivity defined like this:

package com.alvinalexander.testproject2;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // get our html content
        String htmlAsString = getString(R.string.html);      // used by WebView
        Spanned htmlAsSpanned = Html.fromHtml(htmlAsString); // used by TextView

        // set the html content on a TextView
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(htmlAsSpanned);

//        WebView webView = (WebView) findViewById(R.id.webView);
//        webView.loadDataWithBaseURL(null, htmlAsString, "text/html", "utf-8", null);

    }

}

the HTML string displayed in an Android TextView widget looks like this:

As you can see, the TextView does not display some elements properly. In fact, the more HTML you want to use, the more this becomes a problem, because the TextView has very little support for displaying HTML.

Android WebView is better

In fact, the display problems are bad enough that you’re probably better off using a WebView instead of a TextView. If you remove the WebView comments from the code I’ve shown, and comment-out the TextView code, you’ll see that a WebView renders the HTML much better:

Summary

So, while you can render an HTML string in an Android TextView, the question becomes, “Should you do this?” For all but the simplest cases, my guess is that you’ll want to use a WebView instead of a TextView, as demonstrated by this example.

Note: For this example I used a minSdkVersion of 14 and a targetSdkVersion of 21, and the output is shown in a Nexus 5 emulator.