Coder Perfect

In XML, set the TextView text from an html-formatted string resource.

Problem

In my strings.xml file, I have certain fixed strings like:

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

I have a TextView in my layout that 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 simply somestring without any html tags, and hence unformatted.

I’m aware that the formatted text can be set programmatically with

.setText(Html.fromHtml(somestring));

because I’m using it in other areas of my software and it’s functioning fine.

I need an Activity to use this function, but right now my layout is just a simple, more or less static view in plain XML, and I’d rather leave it that way to avoid the overhead of having to create an Activity just to set some text.

Is there something evident that I’m missing? Is it not at all possible? Any assistance or workarounds are much appreciated!

Edit: I just tested a few things, and it appears that xml HTML formatting has certain limitations:

Asked by slup

Solution #1

Just in case anyone stumbles over this, there is a better option that isn’t recorded (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 if you wrap it in a tag.

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

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, include the following:

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

This is, in my opinion, several orders of magnitude more pleasant to deal with:-)

Updated in August 2021: Html.fromHtml(String) was used in my initial response, but it was deprecated in API 24. It is suggested that you use the fromHtml(String,int) form instead.

While FROM HTML MODE LEGACY is likely to work, one of the other flags may be a better fit for your needs.

Finally, there are now numerous third-party libraries that enable it easy to produce Android Spanned text suitable for usage in a TextView using Markdown syntax instead of HTML, like https://noties.io/Markwon.

Answered by Bitbang3r

Solution #2

Although the question is pretty old, I believe the top response here suggests something incorrect (or at least overly complicated):

In Android, you can leverage String resources by calling getString(…) from Java code or using android:text=”@string/…” in your layout XML.

You don’t have to make much changes if you want to use HTML markup in your Strings:

The only characters that you need to escape in your String resources are:

That means you don’t have to escape the tags when adding HTML markup:

<string name="my_string"><b>Hello World!</b> This is an example.</string>

To be sure, only use b>, I and u> in the order they are listed in the manual.

Simply keep using android:text=”@string/…” if you want to use your HTML strings from XML.

The only difference is that if you wish to utilize your HTML strings from Java code, you must now use getText(…) rather than getString(…), because the former preserves the style while the latter removes it.

That’s all there is to it. There is no CDATA and no Html.fromHtml (…).

You’ll only need Html.fromHtml(…) if you used HTML markup to encode your special characters. Then use it with getString(…) This can be necessary if you want to pass the String to String.format(…).

All of this is also detailed in the documentation.

Edit:

There’s no difference between using getText(…) with unescaped HTML (as I suggested) or using CDATA portions with Html.fromHtml (…).

For a comparison, look at the graph below:

Answered by caw

Solution #3

HTML tags must be enclosed in square brackets…

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>

Answered by ekawas

Solution #4

The type of resource string (for example, text/plain or text/html) is not specified in Android. There is, however, a solution that allows the developer to declare this in the XML file.

Once you’ve defined these, you’ll never have to call setText(Html.fromHtml(…)) again to express yourself with HTML in xml files. This approach isn’t part of the API, which surprises me.

This technique works to the point where the text is rendered HTML on the Android studio simulator.

<resources>
<string name="app_name">TextViewEx</string>
<string name="string_with_html"><![CDATA[
       <em>Hello</em> <strong>World</strong>!
 ]]></string>
</resources>

Declare the android ex:isHtml attribute and add it to the custom attribute namespace. Use the TextView subclass as well.

<RelativeLayout
...
xmlns:android_ex="http://schemas.android.com/apk/res-auto"
...>

<tv.twelvetone.samples.textviewex.TextViewEx
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/string_with_html"
    android_ex:isHtml="true"
    />
 </RelativeLayout>
 <resources>
<declare-styleable name="TextViewEx">
    <attr name="isHtml" format="boolean"/>
    <attr name="android:text" />
</declare-styleable>
</resources>
 package tv.twelvetone.samples.textviewex;

 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.Nullable;
 import android.text.Html;
 import android.util.AttributeSet;
 import android.widget.TextView;

public TextViewEx(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewEx, 0, 0);
    try {
        boolean isHtml = a.getBoolean(R.styleable.TextViewEx_isHtml, false);
        if (isHtml) {
            String text = a.getString(R.styleable.TextViewEx_android_text);
            if (text != null) {
                setText(Html.fromHtml(text));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        a.recycle();
    }
}
}

Answered by Steven Spungin

Solution #5

Latest update:

after Android N releases, Html.fromHtml(string);/deprecated.

The code below supports Android N and higher versions…

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(yourHtmlString,Html.FROM_HTML_MODE_LEGACY));
}

else 
{
textView.setText(Html.fromHtml(yourHtmlString));
}

Answered by Ranjithkumar

Post is based on https://stackoverflow.com/questions/3235131/set-textview-text-from-html-formatted-string-resource-in-xml