如何解析API返回的转义HTML并在TextView中正确显示无序列表
Alright, let's break down why your TextView isn't rendering the unordered list correctly and fix it step by step:
First, Fix the Double-Escaped HTML String
Your raw API response is double-escaped — for example, &lt;ul&gt; is actually the result of escaping <ul> twice. Before rendering, you need to decode it back to proper HTML:
// Your original escaped string from the API String rawEscapedHtml = "<ul><li>Without Flavor &amp; Size</li>..."; // Option 1: Use Android's HtmlCompat to decode twice String decodedOnce = HtmlCompat.fromHtml(rawEscapedHtml, HtmlCompat.FROM_HTML_MODE_COMPACT).toString(); String realHtml = HtmlCompat.fromHtml(decodedOnce, HtmlCompat.FROM_HTML_MODE_COMPACT).toString(); // Option 2: Use Apache Commons Lang's StringEscapeUtils (simpler) String realHtml = StringEscapeUtils.unescapeHtml4(StringEscapeUtils.unescapeHtml4(rawEscapedHtml));
Fix List Rendering (Native Android Solution)
Android's native Html.fromHtml ignores <ul> and <li> styling — it just dumps the text without bullets or indentation. To fix this, create a custom TagHandler to handle list tags:
public class ListTagHandler implements TagHandler { private int indentation = 0; private static final int INDENT_PX = 32; // Adjust this for your desired indent size @Override public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { switch (tag.toLowerCase()) { case "ul": case "ol": // Adjust indentation when entering/exiting a list indentation += opening ? INDENT_PX : -INDENT_PX; break; case "li": if (opening) { // Add bullet point output.append("• "); // Apply indentation to the bullet and list item text output.setSpan( new LeadingMarginSpan.Standard(indentation), output.length() - 2, output.length(), Spanned.SPAN_MARK_MARK ); } else { // Add a line break after each list item output.append("\n"); } break; } } }
Then use this handler to parse and display the HTML:
Spanned styledContent = HtmlCompat.fromHtml( realHtml, HtmlCompat.FROM_HTML_MODE_COMPACT, null, new ListTagHandler() ); yourTextView.setText(styledContent);
Alternative: Use a Third-Party Library (Markwon)
If you tried third-party libraries before and they didn't work, you probably skipped decoding the double-escaped string first. Markwon handles HTML lists flawlessly:
- Add the dependency to your
build.gradle:
implementation "io.noties.markwon:core:4.6.2"
- Decode your string and render it:
String realHtml = StringEscapeUtils.unescapeHtml4(StringEscapeUtils.unescapeHtml4(rawEscapedHtml)); Markwon markwon = Markwon.create(context); markwon.setMarkdown(yourTextView, realHtml);
Why Your Previous Attempts Failed
- You didn't decode the double-escaped string, so the parser was seeing
<ul>instead of actual<ul>tags. - Android's native HTML parser doesn't support list styling out of the box — it requires custom handling or a dedicated library.
内容的提问来源于stack exchange,提问作者Ali Habbash

