TextView渲染HTML使用自定义标签

如果需要在一个TextView中,显示多种字体,颜色,大小,粗细等,一种方法是使用SpannableString,另外一种方法就是,使用Html.fromHtml()

但是默认tag比较的少,这里我只列出自己使用的几个,剩下的可以到文档中去查找
android.text.Html

用到过的tag:

  • <font color="#FFFFFF"> </font> 设置颜色
  • <b> </b> 加粗
  • <br/> 换行

使用方法:

这里TextViewSizeLabel就是我们要自定义的标签解析器

1
textView.setText(Html.fromHtml(contentHtml, null, new TextViewSizeLabel()));

首先创建类,实现接口Html.TagHandler,复写handleTag函数。
参数解释:

  • boolean opening 是否为Tag的开始,通过获取开始和结束的位置,来获取需要调整效果的文字位置
  • String tag Tag的名字
  • Editable output 输出的文本
  • XMLReader xmlReader Tag后面的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class TextViewSizeLabel implements Html.TagHandler {
private static final String SIZE_NAME = "size";
private static final String SIZE_VALUE = "value";

private int startIndex = 0;
private int endIndex = 0;
private String sizeValue = "";

@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
//自定义的标签名
if (!tag.toLowerCase().equals(SIZE_NAME)) {
return;
}

//opening 表示标签的开始
if (opening) {
startIndex = output.length();
//获取标签值
sizeValue = getProperty(xmlReader, SIZE_VALUE);
} else {
endIndex = output.length();
//标签结束,对标签部分字符串进行处理
output.setSpan(new AbsoluteSizeSpan(DisplayUtils.dp2px(FormatUtils.parseFloat(sizeValue))),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}

//通过反射获取属性
private String getProperty(XMLReader xmlReader, String property) {
try {
Field elementField = xmlReader.getClass().getDeclaredField("theNewElement");
elementField.setAccessible(true);
Object element = elementField.get(xmlReader);
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++) {
if (property.equals(data[i * 5 + 1])) {
return data[i * 5 + 4];
}
}
} catch (Exception e) {
Timber.e(e);
}
return null;
}
}

编写好之后,就可以使用如下来对文字的大小进行设置了。

1
<size value="12"> </size>
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×