rainbow-android-app

HTML转义和显示

简介

本文主要介绍云助理原生安卓中对html标签的相关处理,包括html转义、以及实现云助理自定义标签的内容。

html转义

云助理收到的消息内容都是经过Html转义,所以在消息列表显示消息内容前,需要使用 Html.fromHtml() 回转对应的内容,然后再显示在界面上。

云助理自定义html标签

云助理对消息标题和简介中的html标签的使用限制比较严,只支持< a>、三个标签、对除此之外的html标签都作为文本显示。

在TextView中显示html链接

用户在消息简介中可以加入 <a><rainbow-a> 标签,实现在客户端消息简介中显示链接,并可在内置浏览器中打开。支持持使用href属性指定链接地址,不支持其他html属性。

客户端收到新消息时,都会进行正则匹配,把转义后的 &lt;a&gt;&lt;rainbow-a&gt; 标签统一替换为<a>

客户端在显示消息简介的时候,为了实现把 <a> 标签显示为html链接样式,并设置点击链接时的打开方式,需要进行如下处理:

1.对要显示的内容进行html编译

CharSequence sequence = Html.fromHtml(text);
SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);

2.依次设置点击html链接时对应的操作:

URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);
for (URLSpan span : urls) {
    makeLinkClickable(strBuilder, span);  //定义点击html链接时的操作
}

3.在makeLinkClickable()中,会获取html链接显示的标题以及对应的url,并定义点击链接时的打开方式。

//获取每个URLSpan对应的标题,作为内置浏览器的标题来显示
int start = strBuilder.getSpanStart(span);
int end = strBuilder.getSpanEnd(span);
int flags = strBuilder.getSpanFlags(span);
final String title = strBuilder.toString().substring(start, end);


ClickableSpan clickable = new ClickableSpan() {
    public void onClick(View view) {
        //指定打开链接的方式
        MixUtil.openLink(context, span.getURL(), title);
    };
}

strBuilder.setSpan(clickable, start, end, flags);
strBuilder.removeSpan(span);

4.最后还需要为显示html内容的TextView增加如下操作,以保证链接可点击。

TextView desc = (TextView) view.findViewById(R.id.desc);
desc.setMovementMethod(LinkMovementMethod.getInstance());

在TextView中通过html样式改变文字样式

云助理提供自定义标签来改变消息中的文字样式,可以改变文字颜色、字体粗细、文字背景色,不支持其他的html样式。文字颜色和背景色的值只支持十六进制颜色值。

示例:
<yzl-style style="color:#AFAFAF;font-weight:bold;background-color:#EEEEEE;>文字样式</yzl-style>

安卓有提供Html.fromHtml()用于显示TextView中的HTML内容,但是有很多限制:

1.只支持显示一部分html标签;
2.支持的HTML标签中只支持很少的一部分属性,包括:<a>的href、<div>的align、<img>的src和<font>的color、size、face属性;
3.color属性只支持十六进制颜色值(即#FFFFFF形式的值),不支持颜色名和rgb颜色值;

由于不支持style属性,为了在TextView中改变文字样式,客户端只能依次实现三种文字样式:

1.文字颜色

正则匹配消息中的标签,获取其中 color 对应的十六进制颜色值,然后在标签外面加上 <font> 标签,并设置 <font> 标签color属性的值为对应文字颜色。

处理前:
<yzl-style style="color:#AFAFAF;font-weight:bold;background-color:#EEEEEE;">文字样式</yzl-style>

处理后:
<font color="#AFAFAF"><yzl-style style="color:#AFAFAF;font-weight:bold;background-color:#EEEEEE;">文字样式</yzl-style></font>

2.文字粗细

正则匹配消息中处理后的标签,并匹配style中是否包含 font-weight:bold; 样式,如果有,说明文字需要加粗,在处理后的标签外加上 <strong> 标签来加粗字体。

处理前:
<font color="#AFAFAF"><yzl-style style="color:#AFAFAF;font-weight:bold;background-color:#EEEEEE;">文字样式</yzl-style></font>

处理后:
<strong><font color="#AFAFAF"><yzl-style style="color:#AFAFAF;font-weight:bold;background-color:#EEEEEE;">文字样式</yzl-style></font></strong>

3.文字背景色

在显示TextView时,正则匹配标签,获取十六进制的背景色值,然后把标签替换为 <yzl-style>{*}</yzl-style>{*} 部分的内容。

然后通过如下操作来改变文本背景色:

//yzlText为<yzl-style>{*}</yzl-style>中{*}部分的内容
strBuilder.replace(start, end, yzlText);
int offset = yzlText.length() - (end - start);
strBuilder.setSpan(new BackgroundColorSpan(Color.parseColor(backgroundColor)),
                start, end + offset, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);