首页 > 编程知识 正文

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

时间:2023-05-04 08:29:53 阅读:272881 作者:909

由于在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显示字体大小和颜色可参考

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。