通过SpannableString设置超链接、颜色、字体
显示效果
代码
public class MainActivity extends Activity {
TextView textView = null;
SpannableString spanStr = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
// 创建一个 SpannableString对象
String data = "字体测试字体大小一半两倍\n前景色背景色\n正常粗体斜体粗斜体\n下划线
删除线\nx1x2\n电话\n邮件\n网站\n短信\n彩信\n地图\n*";
spanStr = new SpannableString(data);
// 设置字体
TypefaceSpan typefaceSpan1 = new TypefaceSpan("monospace");
spanStr.setSpan(typefaceSpan1, 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
TypefaceSpan typefaceSpan2 = new TypefaceSpan("serif");
spanStr.setSpan(typefaceSpan2, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体绝对大小
AbsoluteSizeSpan absSizeSpan1 = new AbsoluteSizeSpan(20);
spanStr.setSpan(absSizeSpan1, 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
AbsoluteSizeSpan absSizeSpan2 = new AbsoluteSizeSpan(20, true);
spanStr.setSpan(absSizeSpan2, 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体相对大小
RelativeSizeSpan relSizeSpan1 = new RelativeSizeSpan(0.5f);
spanStr.setSpan(relSizeSpan1, 8, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
RelativeSizeSpan relSizeSpan2 = new RelativeSizeSpan(2.0f);
spanStr.setSpan(relSizeSpan2, 10, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 设置字体前景色为洋红色
ForegroundColorSpan forColorSpan = new ForegroundColorSpan(
Color.MAGENTA);
spanStr.setSpan(forColorSpan, 13, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体背景色为青色
BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.CYAN);
spanStr.setSpan(bgColorSpan, 16, 19, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体样式
StyleSpan styleSpan1 = new StyleSpan(android.graphics.Typeface.NORMAL);
spanStr.setSpan(styleSpan1, 20, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//正常
StyleSpan styleSpan2 = new StyleSpan(android.graphics.Typeface.BOLD);
spanStr.setSpan(styleSpan2, 22, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//粗体
StyleSpan styleSpan3 = new StyleSpan(android.graphics.Typeface.ITALIC);
spanStr.setSpan(styleSpan3, 24, 26, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//斜体
StyleSpan styleSpan4 = new StyleSpan(
android.graphics.Typeface.BOLD_ITALIC); // 粗斜体
spanStr.setSpan(styleSpan4, 26, 29, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置下划线
UnderlineSpan underlineSpan = new UnderlineSpan();
spanStr.setSpan(underlineSpan, 30, 33, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置删除线
StrikethroughSpan strikeSpan = new StrikethroughSpan();
spanStr.setSpan(strikeSpan, 33, 36, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置上下标
SubscriptSpan subSpan = new SubscriptSpan();
spanStr.setSpan(subSpan, 38, 39, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //下标
SuperscriptSpan superSpan = new SuperscriptSpan();
spanStr.setSpan(superSpan, 40, 41, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//上标
// 超级链接
URLSpan urlSpan1 = new URLSpan("tel:02787807727");
spanStr.setSpan(urlSpan1, 42, 44, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 电话
URLSpan urlSpan2 = new URLSpan("mailto:369950806@qq.com");
spanStr.setSpan(urlSpan2, 45, 47, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 邮件
URLSpan urlSpan3 = new URLSpan("http://www.baidu.com");
spanStr.setSpan(urlSpan3, 48, 50, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 网站
URLSpan urlSpan4 = new URLSpan("sms:02787807727");
spanStr.setSpan(urlSpan4, 51, 53, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 短信
URLSpan urlSpan5 = new URLSpan("mms:02787807727"); // 可使用mms:或者mmsto:
spanStr.setSpan(urlSpan5, 54, 56, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 彩信
URLSpan urlSpan6 = new URLSpan("geo:113.53,29.58");
spanStr.setSpan(urlSpan6, 57, 59, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 地图
// 设置字体宽度大小
ScaleXSpan scaleXSpan = new ScaleXSpan(2.0f);
spanStr.setSpan(scaleXSpan, 57, 59, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置图片
Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
spanStr.setSpan(new ImageSpan(drawable), 60, 61,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spanStr);
textView.setMovementMethod(LinkMovementMethod.getInstance());//添加动作响应
}
}
核心方法讲解:
public void setSpan (Object what, int start, int end, int flags)
对当前内容从start位置到end位置之间(包括start但不包括end)的部分采用what指定的方式进行渲染。
- what:渲染方式,即指定要设置的Style span
- start:起始位置,无论中文、英文,还是换行\n,都占一个位置,从0开始计算起。
- end:结束位置
- flags是用于控制行为的,通常设置为0或Spanned中定义的常量。其中:
常见的Span有:
- AbsoluteSizeSpan(int size)
设置字体大小,参数是绝对数值,相当于Word中的字体大小。默认单位是像素,如果第二个参数的值为true,则字体大小单位为dip。 - RelativeSizeSpan(float proportion)
设置字体大小,参数是相对于默认字体大小的倍数,比如默认字体大小是x, 那么设置后的字体大小就是x*proportion,这个用起来比较灵活,proportion>1就是放大(zoom in), proportion<1就是缩小(zoom out) - ScaleXSpan(float proportion)
缩放字体,与上面的类似,默认为1,设置后就是原来的乘以proportion,大于1时放大(zoon in),小于时缩小(zoom out) - BackgroundColorSpan(int color)
背景着色,参数是颜色数值,可以直接使用android.graphics.Color里面定义的常量,或是用Color.rgb(int, int, int) - ForegroundColorSpan(int color)
前景着色,也就是字的着色,参数与背景着色一致 - TypefaceSpan(String family)
字体,参数是字体的名字,常见取值有:default、default-bold、monospace、serif、sans-serif - StyleSpan(Typeface style)
设置字体样式,参数是android.graphics.Typeface里面定义的常量,比如NORMAL、BOLD、ITALIC、BOLD_ITALIC,分别表示正常,粗体,斜体,粗斜体。 - StrikethroughSpan
如果设置了此风格,会有一条线从中间穿过所有的字,就像被划掉一样
常用的flags有:
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE:不包含两端start和end所在的端点
- Spanned.SPAN_EXCLUSIVE_INCLUSIVE :不包含端start,但包含end所在的端点
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE: 包含两端start,但不包含end所在的端点
- Spanned.SPAN_INCLUSIVE_INCLUSIVE:包含两端start和end所在的端点