您的位置:首页 > 移动开发 > Android开发

android Html.fromHtml font 标签支持设置字体大小和颜色

2017-08-30 17:52 731 查看
由于在android 中的Html源码中对html标签的支持不是很完全,在使用textview加载html自定义字体样式的时候遇到坑了,就是font标签不支持size属性,查看源码中发现没有去解析size属性

// Html源码部分
private static void startFont(SpannableStringBuilder text,
Attributes attributes) {
// 解析颜色
String color = attributes.getValue("", "color");
// 解析face
String face = attributes.getValue("", "face");

int len = text.length();
text.setSpan(new Font(color, face), len, len, Spannable.SPAN_MARK_MARK);
}


所以如下这样写size是没有效果的,只显示颜色

String text = "<font color='red' size='50px'>" + "要显示的数据" + "</font>";
Spanned spanned = Html.fromHtml(text);


==>>>>>>>>>>>>>>>>>>>>>分割线>>>>>>>>>>>>>>>>>>>>>==

由于android对html标签解析最终也是通过各种span进行拼接形成对应的样式:

以下是android中提供的各种span及用途

BackgroundColorSpan 背景色

ClickableSpan 文本可点击,有点击事件

ForegroundColorSpan 文本颜色(前景色)

MaskFilterSpan修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)

MetricAffectingSpan 父类,一般不用

RasterizerSpan 光栅效果

StrikethroughSpan 删除线(中划线)

SuggestionSpan 相当于占位符

UnderlineSpan 下划线

AbsoluteSizeSpan 绝对大小(文本字体)

DynamicDrawableSpan 设置图片,基于文本基线或底部对齐。

ImageSpan 图片

RelativeSizeSpan 相对大小(文本字体)

ReplacementSpan 父类,一般不用

ScaleXSpan 基于x轴缩放

StyleSpan 字体样式:粗体、斜体等

SubscriptSpan 下标(数学公式会用到)

SuperscriptSpan 上标(数学公式会用到)

TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)

TypefaceSpan 文本字体

URLSpan 文本超链接

接下来我们就通过Html.TagHandler来自定义标签实现设置字体大小的功能

此处我定义标签名为:myfont

此处的调用方式如下:

String text = "<myfont color='red' size='50px'>" + "要显示的数据" + "</myfont>";
Spanned spanned = Html.fromHtml(text, null, new HtmlTagHandler("myfont"));


关键代码在HtmlTagHandler里面处理自定义标签myfont:

public class HtmlTagHandler implements Html.TagHandler {
// 自定义标签名称
private String tagName;

// 标签开始索引
private int startIndex = 0;
// 标签结束索引
private int endIndex = 0;
// 存放标签所有属性键值对
final HashMap<String, String> attributes = new HashMap<>();

public HtmlTagHandler(String tagName) {
this.tagName = tagName;
}

@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
// 判断是否是当前需要的tag
if (tag.equalsIgnoreCase(tagName)) {
// 解析所有属性值
parseAttributes(xmlReader);

if (opening) {
startHandleTag(tag, output, xmlReader);
}
else {
endEndHandleTag(tag, output, xmlReader);
}
}
}

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

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

// 获取对应的属性值
String color = attributes.get("color");
String size = attributes.get("size");
size = size.split("px")[0];

// 设置颜色
if (!TextUtils.isEmpty(color)) {
output.setSpan(new ForegroundColorSpan(Color.parseColor(color)), startIndex, endIndex,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
// 设置字体大小
if (!TextUtils.isEmpty(size)) {
output.setSpan(new AbsoluteSizeSpan(Integer.parseInt(size)), startIndex, endIndex,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}

/**
* 解析所有属性值
*
* @param xmlReader
*/
private void parseAttributes(final XMLReader xmlReader) {
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++) {
attributes.put(data[i * 5 + 1], data[i * 5 + 4]);
}
} catch (Exception e) {

}
}
}


如果以下方式没有效果:

String text = "<myfont color='red' size='50px'>" + "要显示的数据" + "</myfont>";
Spanned spanned = Html.fromHtml(text, null, new HtmlTagHandler("myfont"));


可在myfont标签前面添加一个随意标签实现如:

String text = "<p><myfont color='red' size='50px'>" + "要显示的数据" + "</myfont></p>";
Spanned spanned = Html.fromHtml(text, null, new HtmlTagHandler("myfont"));


如果不想自定义tag显示字体大小和颜色可参考
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: