富文本的核心,就是让TextView支持HTML格式文本,复合文本,超链接
1.HTML格式文本,这里就涉及到一个方法:
Spanned spanned = Html.fromHtml(html);
将带标签的String类型解析成android下可识别HTML标签的Spanned类型。String和Spanned都实现了CharSequence接口,所以TextView可以解读Spanned。
String html="<font color='red'>test1</font> <br>";
html+="<font color='#0000FF'> <big> <i> test2 </i> </big> <font>";
html+="<font color='@"+android.R.color.black+"'> <tt> <b> <big> <u> test3 </u> </big>";
Spanned spanned = Html.fromHtml(html);
text.setText(spanned);
显示效果如下:
2.android下对HTML格式文本的支持度很好,这里介绍一些常用的标签:
< font>:设置颜色和字体
< big>:设置大号字
< small>:设置小号字
< i>:斜体
< b>:粗体
< tt>:等宽字体(Monospace)
< br>:换行(行与行之间没有空行)
< p>:换行(行与行之间的空行)
< a>:链接地址
< img>:插入图像
3.在实际开发中,富文本的各种标签的使用,一般都会包装成工具类:
String content = r("红色") + ", 警戒, "+g("绿巨人")+", <big><font color='#FFC0CB'>粉色</font></big>, " +
b("蓝色");
@NonNull
public static String r(String str) { // red
return String.format("<font color='red'>%s</font>", str);
}
@NonNull
public static String g(String str) { // green
return String.format("<font color='#00FF00'>%s</font>", str);
}
@NonNull
public static String b(String str) { // blue
return String.format("<font color='#0000FF'>%s</font>", str);
}
使用了String类的format()方法,原理是C语言的占位思想。
4.使用复合文本,实现图文混排
//px转dip
int bound = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());
TextView tv_emoji = (TextView) findViewById(R.id.tv_emoji);
String text1 = "滑稽树下滑稽果,滑稽树下你和我";
//将字符串转化成符合文本,可设置各种样式
SpannableString spannable = new SpannableString(text1);
// 获取图片
Drawable drawable = getResources().getDrawable(R.drawable.joy);
// 设置四边宽高
drawable.setBounds(0, 0, bound, bound);
// 构建图片区域,格式为文字在上
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
// 替换指定位置的内容
spannable.setSpan(imageSpan, 7, 8 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv_emoji.setText(spannable);
5.实现TextView里的超链接:
- 跳转到网页的超链接
- 隐式意图,如打电话的超链接
- 自定义的超链接
String linkText = "百度,电话,@大保健";
TextView tv_link = (TextView) findViewById(R.id.tv_link);
// 包含链接时, 设置此属性
tv_link.setMovementMethod(LinkMovementMethod.getInstance());
SpannableString link = new SpannableString(linkText);
//跳转到网页
link.setSpan(new URLSpan("https://m.baidu.com"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//隐式意图
link.setSpan(new URLSpan("tel:110"), 3, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//自定义超链接
link.setSpan(new MyURLSpan("来人!扶我去大保健!"), 6, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv_link.setText(link);
/**
* 自定义超链接
*/
class MyURLSpan extends URLSpan{
public MyURLSpan(String url) {
super(url);
}
@Override
public void onClick(View widget) {
String url = getURL();
Toast.makeText(MainActivity.this, url, Toast.LENGTH_SHORT).show();
}
}
6.富文本的进阶
纵观以上这几个使用方法,其实都逃不过三点:
* 将String类型转换成SpannableString类型。
* 根据需求选用相应的文本类型。—->Spanned,ImageSpan ,URLSpan
* 替换原来的内容——>setSpan
在setSpan时,必须传一个Flag值,这个值有什么作用呢?这里用EditText来演示。
EditText et_spaned = (EditText) findViewById(R.id.et_spaned);
String text2 = "_前包后不包_后包前不包_前后都包括_前后都不包_";
SpannableString flag = new SpannableString(text2);
flag.setSpan(new ForegroundColorSpan(Color.RED), 1, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
flag.setSpan(new ForegroundColorSpan(Color.GREEN), 7, 12, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
flag.setSpan(new ForegroundColorSpan(Color.BLUE), 13, 18, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
flag.setSpan(new ForegroundColorSpan(Color.MAGENTA), 19, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
et_spaned.setText(flag);
其实这里的Flag就是一种替换规则:
* Spanned.SPAN_INCLUSIVE_EXCLUSIVE ===》包前不包后
* Spanned.SPAN_EXCLUSIVE_INCLUSIVE====》包后不包前
* Spanned.SPAN_INCLUSIVE_INCLUSIVE====》前后都包
* Spanned.SPAN_EXCLUSIVE_EXCLUSIVE=====》前后都不包