自定义解析Html标签

     Android支持部分原生Html标签,通过textview.setText(Html.formHtml(s))方式将文本以Html的方式格式化显示在TextView中。在Android-25以上的SDK支持大部分标签,包括<font/>、<span/>标签等等。但在不同的SDK版本上对标签的属性上支持不一样,在Android SDK-25以下版本<span/>标签不支持bg-color的Html属性。如果想要在不同的SDK版本都能显示这个效果可以通过自定义标签来解决。

       首先来了解一下源码,分析一下为什么在Android SDK-25以下的<span/>标签bg-color属性不支持。

        先看一下SDK25的源码:

        自定义解析Html标签

        从源码可以看出,这里处理了html格式的前景色和背景色。

        接下来看一下SDK23的源码:

        自定义解析Html标签

        从源码可以看出,这里只处理了前景色,对背景色没有进行任何的处理。所以在SDK25一下的版本Html原生方式添加背景色属性是不会被识别的。

        用自定义标签解决问题:

        1)自定义Html标签,写出你自定义的格式。

              例如:

<wyl style=\" bg-color : #EDEEEE  \">" +"自定义Html标签" + "</wyl>"

textView.setText(Html.fromHtml(
<wyl style=\" bg-color : #EDEEEE  \">" +"自定义Html标签" + "</wyl>, null, new ParseHtmlTagHandler()))
解析ParseHtmlTagHandler类代码:


public class ParseHtmlTagHandler implements Html.TagHandler {

    private int startIndex = 0;
    private int stopIndex = 0;
    final HashMap<String, String> attributes = new HashMap<String, String>();
    private static final String SPAN = "wyl";

    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
        processAttributes(xmlReader);
        if (TextUtils.equals(tag, SPAN)) {
            if (tag.equalsIgnoreCase(SPAN)) {
                if (opening) {
                    startFont(tag, output, xmlReader);
                } else {
                    endFont(tag, output, xmlReader);
                }
            }
        }
    }

    public void startFont(String tag, Editable output, XMLReader xmlReader) {
        startIndex = output.length();
    }

    public void endFont(String tag, Editable output, XMLReader xmlReader) {
        stopIndex = output.length();

        String backGroundColor = attributes.get("style");
        if (!TextUtils.isEmpty(backGroundColor)) {
            output.setSpan(new BackgroundColorSpan(Color.parseColor("#edeeee")), startIndex, stopIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }

    private void processAttributes(final XMLReader xmlReader) {
        try {
            Field elementField = xmlReader.getClass().getDeclaredField("theNewElement");
            elementField.setAccessible(true);
            Object element = elementField.get(xmlReader);
            if (element == null) {
                return;
            }
            Field attsField = element.getClass().getDeclaredField("theAtts");
            attsField.setAccessible(true);
            Object atts = attsField.get(element);
            Field dataField = atts.getClass().getDeclaredField("data");
            dataField.setAccessible(true);
            String[] data = (String[]) dataField.get(atts);
            Field lengthField = atts.getClass().getDeclaredField("length");
            lengthField.setAccessible(true);
            int len = (Integer) lengthField.get(atts);

            for (int i = 0; i < len; i++) {
                attributes.put(data[i * 5 + 1], data[i * 5 + 4]);
            }
        } catch (Exception e) {
         e.printStackTrace();
} }

这里采用的方式是解析自定已标签,使用Spanned方式添加的背景色效果。其实在高版本的添加背景色效果上也是使用的Spanned。