自定义解析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格式的前景色和背景色。

        接下来看一下SDK23的源码:

        

        从源码可以看出,这里只处理了前景色,对背景色没有进行任何的处理。所以在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。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中使用Freemarker可以非常方便地进行模板渲染,但是默认的列表循环标签可能不能完全满足我们的需求。这时我们可以自定义一个列表循环标签来满足我们的需求。 以下是一个简单的自定义列表循环标签示例: 首先我们创建一个类 extending `TemplateDirectiveModel`,并实现 `execute()` 方法。在该方法中,我们解析参数,准备数据并调用模板引擎进行渲染。 ```java @Component public class CustomLoopTagDirective implements TemplateDirectiveModel { private static final String PARAM_NAME_FROM = "from"; private static final String PARAM_NAME_TO = "to"; private static final String PARAM_NAME_STEP = "step"; private static final String PARAM_NAME_VAR = "var"; @Autowired private Configuration configuration; @Override public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { int from = Integer.parseInt(params.get(PARAM_NAME_FROM).toString()); int to = Integer.parseInt(params.get(PARAM_NAME_TO).toString()); int step = Integer.parseInt(params.get(PARAM_NAME_STEP).toString()); String var = params.get(PARAM_NAME_VAR).toString(); List<Integer> list = new ArrayList<>(); for (int i = from; i <= to; i += step) { list.add(i); } env.setVariable(var, configuration.getObjectWrapper().wrap(list)); if (body != null) { body.render(env.getOut()); } } } ``` 我们在这个类上使用 `@Component` 注解,将这个类注册为一个Spring Bean,这样我们就可以在模板中使用这个标签了。 在 `execute()` 方法中,我们首先解析 `from`、`to`、`step` 和 `var` 四个参数。然后我们根据这些参数计算出一个包含整数的列表,并将它作为一个变量存储在模板引擎的环境中。 最后,我们调用 `body.render()` 方法进行渲染,将渲染结果输出到 `env.getOut()` 中。 在模板中使用自定义的循环标签: ```html <@loop from=1 to=10 step=2 var="i"> ${i} </@loop> ``` 我们可以在模板中使用这个标签。在这个例子中,我们将会输出 `1, 3, 5, 7, 9` 这五个整数。 注意:在使用自定义标签时,需要在模板中使用 `@` 符号来引用这个标签,比如 `@loop`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值