androidspannablestringandroid-7.0-nougat

Html Tag Handler not called in Android N for "ul", "li"


We have a custom TagHandler in our app for bulleted list etc.

html = "<ul><li>First item</li><li>Second item</li></ul>";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
  result = Html.fromHtml(html,Html.FROM_HTML_MODE_LEGACY, null, new ListHTMLTagHandler(density));
} else {
  //noinspection deprecation
  result = Html.fromHtml(html, null, new ListHTMLTagHandler(density));
}

The handleTag() function in my TagHandler is called for ul, li in API-23 and below but not called in API-24 (Android N).


Solution

  • It is evident from the source of Html.java that, TagHandler.handleTag() is called only if the framework doesn't process it, itself.

    Currently, the framework doesn't seem to process it well. Android N li tag handling

    But even if it did it well, you would want to customize it anyway. The best way to deal with this is to replace the default ul, li tags with your own tags. Since the framework won't process your custom tags, your TagHandler will be asked to handle it.

    static final String UL = "custom-ul";
    static final String OL = "custom-ol";
    static final String DD = "custom-dd";
    static final String LI = "custom-li";
    
    public static String customizeListTags(@Nullable String html) {
      if (html == null) {
        return null;
      }
      html = html.replace("<ul", "<" + UL);
      html = html.replace("</ul>", "</" + UL + ">");
      html = html.replace("<ol", "<" + OL);
      html = html.replace("</ol>", "</" + OL + ">");
      html = html.replace("<dd", "<" + DD);
      html = html.replace("</dd>", "</" + DD + ">");
      html = html.replace("<li", "<" + LI);
      html = html.replace("</li>", "</" + LI + ">");
      return html;
    }
    

    And then you can process your html string like

    html = customizeListTags(html);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
      result = Html.fromHtml(html,Html.FROM_HTML_MODE_LEGACY, null, new CustomTagHandler());
    } else {
      //noinspection deprecation
      result = Html.fromHtml(html, null, new CustomTagHandler());
    }