Android Html.fromHtml 用法详解
1、Html.fromHtml 基本用法
Html.fromHtml() 是 Android 中用于将 HTML 字符串转换为可显示的 Spanned 对象的方法,它可以将 HTML 标签转换为 Android 中的格式化文本,实现文本样式。
基本功能:
- 将 HTML 字符串转换为 Spanned 对象
- 支持常用的 HTML 标签
- 可以为文字设置颜色、大小、粗体、斜体等样式
- 适用于 TextView 显示格式化文本
常用 HTML 标签:
- <b>:粗体
- <i>:斜体
- <u>:下划线
- <font>:设置字体颜色和大小
- <br>:换行
- <p>:段落
- <a>:超链接
- <img>:图片
基本用法示例:
// 简单的 HTML 字符串
String htmlText = "<b>粗体</b> 和 <i>斜体</i> 和 <u>下划线</u>";
Spanned spanned = Html.fromHtml(htmlText);
textView.setText(spanned);
// 设置文字颜色和大小
String htmlText2 = "<font color='color='#FF0000'>红色文字</font> " +
"<font size='5'>大号文字</font>";
Spanned spanned2 = Html.fromHtml(htmlText2);
textView.setText(spanned2);
// 组合使用
String htmlText3 = "<p><b>标题</b></p>" +
"<p><font color='#0000FF'>蓝色段落文字</font></p>" +
"<p><a href='https://www.example.com'>超链接</a></p>";
Spanned spanned3 = Html.fromHtml(htmlText3);
textView.setText(spanned3);
textView.setMovementMethod(LinkMovementMethod.getInstance());
// 处理图片
String htmlText4 = "带图片的文本 <img src='image_url'>";
Spanned spanned4 = Html.fromHtml(htmlText4, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
// 返回图片
Drawable drawable = getResources().getDrawable(R.drawable.icon);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
return drawable;
}
}, null);
textView.setText(spanned4); 注意事项:
- 在 Android N 及以上版本,推荐使用 Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY)
- 需要导入 android.text.Html 类
- 对于超链接,需要设置 setMovementMethod 才能点击
- 对于图片,需要提供 ImageGetter
2、Html.TagHandler 的使用
Html.TagHandler 是 Html.fromHtml() 中的一个接口,用于处理 HTML 中的自定义标签。当 Html.fromHtml() 遇到无法识别的标签时,会调用 TagHandler 来处理。
TagHandler 接口方法:
- handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader)
- opening:是否为开始标签
- tag:标签名称
- output:输出文本
- xmlReader:XML 读取器
基本使用示例:
// 自定义 TagHandler
class CustomTagHandler implements Html.TagHandler {
private int startIndex = 0;
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("custom")) {
if (opening) {
startIndex = output.length();
} else {
int endIndex = output.length();
// 为自定义标签内的文字设置红色
output.setSpan(new ForegroundColorSpan(Color.RED),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
}
// 使用自定义 TagHandler
String htmlText = "<custom>自定义标签文字</custom>";
Spanned spanned = Html.fromHtml(htmlText, null, new CustomTagHandler());
textView.setText(spanned); 处理多个自定义标签示例:
class MultiTagHandler implements Html.TagHandler {
private int startIndex = 0;
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("color")) {
if (opening) {
startIndex = output.length();
} else {
int endIndex = output.length();
output.setSpan(new ForegroundColorSpan(Color.BLUE),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else if (tag.equalsIgnoreCase("size")) {
if (opening) {
startIndex = output.length();
} else {
int endIndex = output.length();
output.setSpan(new AbsoluteSizeSpan(20, true),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else if (tag.equalsIgnoreCase("highlight")) {
if (opening) {
startIndex = output.length();
} else {
int endIndex = output.length();
output.setSpan(new BackgroundColorSpan(Color.YELLOW),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
// 使用多个自定义标签
String htmlText = "<color>蓝色文字</color> <size>大号文字</size> <highlight>高亮文字</highlight>";
Spanned spanned = Html.fromHtml(htmlText, null, new MultiTagHandler());
textView.setText(spanned); TagHandler 的优势:
- 可以处理自定义标签
- 可以组合多种 Span
- 灵活性高,可以实现复杂的样式
- 与 Html.fromHtml() 无缝集成
3、实际应用与最佳实践
3.1、为文字设置颜色和大小
使用 Font 标签设置颜色和大小:
// 使用 font 标签设置颜色
String htmlText = "<font color='#FF0000'>红色</font> " +
"<font color='#00FF00'>绿色</font> " +
"<font color='#0000FF'>蓝色</font>";
Spanned spanned = Html.fromHtml(htmlText);
textView.setText(spanned);
// 使用 font 标签设置大小
String htmlText2 = "<font size='1'>小号</font> " +
"<font size='3'>中号</font> " +
"<font size='7'>大号</font>";
Spanned spanned2 = Html.fromHtml(htmlText2);
textView2.setText(spanned2);
// 组合使用
String htmlText3 = "<font color='#FF0000' size='5'>红色大号文字</font>";
Spanned spanned3 = Html.fromHtml(htmlText3);
textView3.setText(spanned3);
使用 TagHandler 实现更灵活的颜色和大小设置:
class ColorSizeTagHandler implements Html.TagHandler {
private int startIndex = 0;
private String currentColor = null;
private int currentSize = 0;
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("mytext")) {
if (opening) {
startIndex = output.length();
// 解析标签属性
try {
// 从 XMLReader 获取属性中获取 color 和 size
// 这里简化处理,实际需要解析 XML 属性
currentColor = "#FF0000";
currentSize = 18;
} catch (Exception e) {
e.printStackTrace();
}
} else {
int endIndex = output.length();
// 设置颜色
if (currentColor != null) {
output.setSpan(new ForegroundColorSpan(Color.parseColor(currentColor)),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
// 设置大小
if (currentSize > 0) {
output.setSpan(new AbsoluteSizeSpan(currentSize, true),
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
}
3.2、常见样式组合
组合使用多种 HTML 标签实现复杂的文本样式:
// 组合多个标签
String htmlText = "<b><font color='#FF0000'>红色粗体</font></b><br>" +
"<i><font color='#0000FF'>蓝色斜体</font></i><br>" +
"<u><font size='5'>大号下划线</font></u>";
Spanned spanned = Html.fromHtml(htmlText);
textView.setText(spanned);
// 使用段落
String htmlText2 = "<p><b>标题</b></p>" +
"<p>这是第一段文字,包含 <font color='#FF0000'>红色</font> 和 <i>斜体</i></p>" +
"<p>这是第二段文字,带 <a href='https://www.example.com'>超链接</a></p>";
Spanned spanned2 = Html.fromHtml(htmlText2);
textView2.setText(spanned2);
textView2.setMovementMethod(LinkMovementMethod.getInstance());
3.3、性能优化
- 避免在列表中频繁使用 Html.fromHtml()
- 对于静态文本,可以预先生成 Spanned 对象并缓存
- 对于复杂的样式,考虑使用 SpannableStringBuilder 直接构建
- 对于大量文本,考虑使用 TextView 的 Span 直接设置样式
示例缓存 Spanned 对象:
public class HtmlCache {
private static final Map<String, Spanned> cache = new HashMap<>();
public static Spanned getHtml(String html) {
if (cache.containsKey(html)) {
return cache.get(html);
}
Spanned spanned = Html.fromHtml(html);
cache.put(html, spanned);
return spanned;
}
}
// 使用缓存
Spanned spanned = HtmlCache.getHtml("<b>缓存的 HTML</b>");
textView.setText(spanned);
3.4、注意事项
- Html.fromHtml() 不支持所有 HTML 标签
- 对于复杂的布局,考虑使用 WebView
- 注意处理图片需要 ImageGetter
- 超链接需要设置 setMovementMethod
- 在不同 Android 版本上可能有差异
- 对于复杂的样式,直接使用 SpannableStringBuilder 可能更灵活
Html.fromHtml() 是 Android 中处理格式化文本的强大工具,通过它可以方便地将 HTML 字符串转换为可显示的格式化文本。配合 TagHandler,可以实现更灵活的自定义标签处理。
在实际开发中:
- 常用的简单文本样式可以使用 Html.fromHtml() 快速实现
- 复杂的自定义标签可以使用 TagHandler 处理
- 注意性能优化,避免频繁调用
- 对于超链接和图片需要额外处理
掌握 Html.fromHtml() 和 TagHandler 的使用,可以大大简化文本格式化的工作,提高开发效率。