版权声明
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11227711.html
前言
SpannableString,是google提供用来处理富文本的功能类.支持很多文本内容的效果变化.另外,它也是Android实现富文本编辑器的关键.
SpannableStringBuilder是用于实现多个SpannableString拼接的实现类,类似于Java的StringBuilder。此类下面也会简单说明,主要还是了解SpannableString。
关键API详解
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00")) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
这是一个简单使用的demo,我们用这个demo来讲解一些关键点.
这行代码的关键是setSpan(Object what, int start, int end, int flags)方法,这个方法在后面的文字处理将会一直使用到. setSpan有四个参数我们一个一个来讲解:
第一个参数 Object what 这个参数主要是提供你需要改变字符串的效果实现类,后续会一一讲解并且给出效果图
第二个参数 int start 这个参数是需要改变的字符串的起始位置
第三个参数 int end 这个参数是需要改变的字符串的结束位置
第四个参数 int flags 是一些字符串新增效果的影响范围,您可以参考这篇博客https://www.jianshu.com/p/1956e15c9a27这位大神讲解的十分详细了.本着就算是看懂了也要敲一敲代码记录的想法,下面也会说明一下常用的4种方法
public static final int SPAN_INCLUSIVE_EXCLUSIVE = SPAN_MARK_MARK;
在前面/范围内增加字符,新增字符会跟随效果.
在后面增加字符,新增字符不会跟随效果
效果图:
public static final int SPAN_INCLUSIVE_INCLUSIVE = SPAN_MARK_POINT;
在前面/范围内/后面增加字符,新增字符会跟随效果.
效果图:
public static final int SPAN_EXCLUSIVE_EXCLUSIVE = SPAN_POINT_MARK;
在范围内增加字符,新增字符会跟随效果.
在前面/后面增加字符,新增字符不会跟随效果
效果图:
public static final int SPAN_EXCLUSIVE_INCLUSIVE = SPAN_POINT_POINT;
在范围内/后面增加字符,新增字符会跟随效果.
在前面增加字符,新增字符不会跟随效果.
效果图:
代码里还有一些其他的常量,但是测试后其他都是这四种基本里一样的效果.也实在是没看懂google的注释.....
文字颜色
以下代码将一段文字变成红色
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00")) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
ForegroundColorSpan 注意这个类是关键,他实现文字颜色改变.
效果图:
文字背景颜色
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new BackgroundColorSpan(Color.parseColor("#FFFF0C00")) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
BackgroundColorSpan 注意这个类是关键,他实现文字背景颜色改变.
效果图:
字体
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new TypefaceSpan("sans-serif") //new TypefaceSpan(Typeface.SANS_SERIF) 或者使用这个方法 , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图(系统自带的演示字体效果不明显):
字体大小
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new AbsoluteSizeSpan(50) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
粗体
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StyleSpan(Typeface.BOLD) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
斜体
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StyleSpan(Typeface.ITALIC) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
粗体和斜体
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StyleSpan(Typeface.BOLD_ITALIC) , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
另外还有一个Typeface.NORMAL 正常值就不演示了
效果图:
删除线
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StrikethroughSpan() , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
下划线
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new UnderlineSpan() , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
上标
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new SuperscriptSpan() , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
下标
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new SubscriptSpan() , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
插入图片
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); ImageSpan span = new ImageSpan(bitmap); SpannableString spannableString = new SpannableString(content); spannableString.setSpan(span , 0 , 1 , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
或者
String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher, null); //读取图片 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());//设置边界 图片显示范围 ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);//ImageSpan.ALIGN_BASELINE 是对齐方式,这个是基线对齐 SpannableString spannableString = new SpannableString(content); spannableString.setSpan(span , 0 , 1 , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果图:
点击事件
mTextView.setMovementMethod(LinkMovementMethod.getInstance());//这是关键,只有TextView添加这个后才能有点击事件 mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改点击后的背景色 String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(@NonNull View widget) { Toast.makeText(MainActivity.this, "你点击了创业未半", Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(@NonNull TextPaint ds) { //改变选中文字的颜色或者样式,注意这里的TextPaint 其实是Paint,可以参考Paint的绘制添加其他效果. ds.setColor(Color.RED); // super.updateDrawState(ds); } }; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(clickableSpan , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
setMovementMethod是重中之重,只有设置了才能有 点击功能
另外,如果你需要设置文字的各种样式,比如 取消下划线 ds.setUnderlineText(false) 改变 字体颜色 请在updateDrawState(@NonNull TextPaint ds) 方法里设置
效果图:
超链接
电话
mTextView.setMovementMethod(LinkMovementMethod.getInstance());//这是关键,只有TextView添加这个后才能有点击事件 mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改点击后的背景色 String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new URLSpan("tel:10086") , content.indexOf("创业") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
注意!使用超链接,依然要设置setMovementMethod,另外URLSpan也是可以重写点击事件的.
效果图:
与使用Intent的超链接类似,也是支持几个通用的超链接,都需要你输入正确的前缀
mailto:123456@qq.com
http://www.baidu.com
sms:123456
mms:123456
geo: 38.899533,-77.036476
SpannableStringBuilder 的功能使用
这个类是用于实现多个SpannableString文字拼接的。这里举一个例子进行说明,假如我们要实现下面图片的效果:
用户协议与隐私政策需要分别的点击效果。
代码如下:
private void initAgreementAndPrivacy() { SpannableStringBuilder builder = new SpannableStringBuilder(); builder.append("进入系统即同意"); String userAgreement = "《用户协议》"; SpannableString userAgreementSpannable = new SpannableString(userAgreement); userAgreementSpannable.setSpan(new ClickableSpan() { @Override public void onClick(@NonNull View widget) { //用户协议点击 } @Override public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setColor(Color.WHITE); ds.setUnderlineText(false); } }, 0, userAgreement.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); builder.append(userAgreementSpannable); builder.append("和"); String privacyPolicy = "《隐私政策》"; SpannableString privacyPolicySpannable = new SpannableString(privacyPolicy); privacyPolicySpannable.setSpan(new ClickableSpan() { @Override public void onClick(@NonNull View widget) { //隐私政策点击 } @Override public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setColor(Color.WHITE); ds.setUnderlineText(false);//取消下划线 } }, 0, userAgreement.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); builder.append(privacyPolicySpannable); mArguementText.setMovementMethod(LinkMovementMethod.getInstance()); mArguementText.setHighlightColor(getResources().getColor(android.R.color.transparent, null)); mArguementText.setText(builder); }
其他Span
上面的span只是一些常用的span演示,但是其实还有更多的span可以选择和使用,他们都在这个目录中.在这个目录下还有以下这些span.如果后续有时间我会一一实验使用这些span以判断他们的功能.
放弃富文本效果,提取文本
之前有端时间苦恼怎么提取不带富文本格式的文本,因为源代码的有很多方法并没有注释,所以蛋疼了很久..,后面突然发现,直接使用toString()方法就行
spannableString.toString()
END
SpannableStringBuilder
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11227711.html