1.SpannableString与SpannableStringBuilder简介
SpannableStringBuilder,SpannableString其实和String一样,都是一种字符串类型。不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示。比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉。SpannableString与SpannableStringBuilder区别就如String和StringBuilder一样。
2. setSpan()
void setSpan (Object what, int start, int end, int flags)
object what :对应的各种Span,后面会提到;
int start:开始应用指定Span的位置,索引从0开始
int end:结束应用指定Span的位置,包不包含两头的数据,取决于flags的值
flag的取值
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含start和end所在的端点 (a,b)
Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端点 (a,b]
Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含start,但不包含end所在的端点 [a,b)
Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含start和end所在的端点 [a,b]
3. object what 各种设置
3.1字体颜色(ForegroundColorSpan)
/**
* 设置字体颜色
*/
private void setColor() {
String content = "SpannableStringBuilder 简介";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#FF4040"));
stringBuilder.setSpan(foregroundColorSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.2背景颜色(BackgroundColorSpan)
这个是设置无圆角的背景,如果是要设置带圆角的背景,可查看本文最后的自定义类RoundBackgroundColorSpan。
/**
* 设置背景颜色
*/
private void setBackgroundColor() {
String content = "SpannableStringBuilder 简介";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
//背景颜色
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor("#FF4040"));
stringBuilder.setSpan(backgroundColorSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.3文本可点击,有点击事件(ClickableSpan)
/**
* 设置文本点击事件
*/
private void setClickableSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, "可点击", Toast.LENGTH_LONG).show();
}
@Override
public void updateDrawState(TextPaint ds) {
//去掉可点击文字的下划线
ds.setUnderlineText(false);
}
};
//文本可点击,有点击事件
stringBuilder.setSpan(clickableSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置此方法后,点击事件才能生效
contentTv.setMovementMethod(LinkMovementMethod.getInstance());
此句用来消除点击后的背景异色
contentTv.setHighlightColor(getResources().getColor(android.R.color.transparent));
contentTv.setText(stringBuilder);
}
3.4 模糊效果(BlurMaskFilter)
/**
* 设置模糊效果
*/
private void setBlurMaskFilterSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
MaskFilter filter = new BlurMaskFilter(4.0f, BlurMaskFilter.Blur.OUTER);
MaskFilterSpan maskFilterSpan = new MaskFilterSpan(filter);
stringBuilder.setSpan(maskFilterSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.5 删除线效果 (StrikethroughSpan)
/**
* 设置删除线效果 (StrikethroughSpan)
*/
private void setStrikethroughSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
stringBuilder.setSpan(new StrikethroughSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setMovementMethod(LinkMovementMethod.getInstance());
contentTv.setText(stringBuilder);
}
3.6 下划线效果(UnderlineSpan)
/**
* 设置下划线效果(UnderlineSpan)
*/
private void setUnderlineSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
stringBuilder.setSpan(new UnderlineSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.7 字体绝对大小效果(AbsoluteSizeSpan)
/**
* 设置字体绝对大小效果(AbsoluteSizeSpan)
*/
private void setAbsoluteSizeSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
AbsoluteSizeSpan ab=new AbsoluteSizeSpan(30,true);
//文本字体绝对的大小
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.8 设置图片(DynamicDrawableSpan)基于底部
/**
* 设置图片(DynamicDrawableSpan)基于底部
*/
private void setDynamicDrawableSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
DynamicDrawableSpan dynamicDrawableSpan = new DynamicDrawableSpan() {
@Override
public Drawable getDrawable() {
Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0, 0, 50, 50);
return drawable;
}
};
stringBuilder.setSpan(dynamicDrawableSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.9 设置图片(ImageSpan )
/**
* 设置设置图片(ImageSpan )
*/
private void setImageSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher_round);
drawable.setBounds(0, 0, 100, 100);
ImageSpan ab = new ImageSpan(drawable);
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.10 相对字体大小(RelativeSizeSpan )
/**
* 设置相对字体大小(RelativeSizeSpan )
*/
private void setRelativeSizeSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
stringBuilder.setSpan(new RelativeSizeSpan(3.0f), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.10 基于X的缩放(ScaleXSpan )
/**
* 设置 基于X的缩放(ScaleXSpan )
*/
private void setScaleXSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
stringBuilder.setSpan(new ScaleXSpan(3.0f), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.11 字体样式:粗体、斜体等(StyleSpan )
/**
* 设置字体样式:粗体、斜体等(StyleSpan )
*/
private void setStyleSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
StyleSpan ab = new StyleSpan(Typeface.BOLD_ITALIC);
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.12 上标(SubscriptSpan )
/**
* 设置上标(SuperscriptSpan )
*/
private void setSuperscriptSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
SuperscriptSpan ab = new SuperscriptSpan();
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.14 下标(SubscriptSpan )
/**
* 设置下标(SubscriptSpan )
*/
private void setSubscriptSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
stringBuilder.setSpan(new SubscriptSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.12 字体、大小、样式和颜色(TextAppearanceSpan)
/**
* 设置字体、大小、样式和颜色(TextAppearanceSpan)
*/
private void setTextAppearanceSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
//自定义文本样式
TextAppearanceSpan ab = new TextAppearanceSpan(this, android.R.style.TextAppearance_Medium);
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.13 文本字体(TypefaceSpan )
/**
* 设置文本字体(TypefaceSpan )
*/
private void setTypefaceSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
//文字字体
TypefaceSpan ab = new TypefaceSpan("serif");
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
3.14 文本超链接(URLSpan )
/**
* 设置文本超链接(URLSpan )
*/
private void setURLSpan() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
URLSpan ab = new URLSpan("http://www.baidu.com");
stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setMovementMethod(new LinkMovementMethod());
contentTv.setText(stringBuilder);
}
3.15 使用带圆角的按钮背景
/**
* 设置带有圆角的背景
*/
private void setRoundBackgroundColor() {
String content = "CSDN-专业IT技术社区";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
//背景颜色
RoundBackgroundColorSpan roundBackgroundColorSpan = new RoundBackgroundColorSpan(
getResources().getColor(R.color.color_yellow),
getResources().getColor(R.color.color_white),
getResources().getDimensionPixelSize(R.dimen.textsize_28px),
getResources().getDimensionPixelSize(R.dimen.view_distance_6));
stringBuilder.setSpan(roundBackgroundColorSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTv.setText(stringBuilder);
}
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.style.ReplacementSpan;
/**
* author : wyy
* time : 2019/1/22
* desc : 自定义 span 的圆角背景图片,具体尺寸可能要看情况,不一定通用
*/
public class RoundBackgroundColorSpan extends ReplacementSpan {
private int bgColor;
private int textColor;
private int textSize;
private int mRadius;
private int mSize;
public RoundBackgroundColorSpan(int bgColor, int textColor, int textSize, int radius) {
super();
this.bgColor = bgColor;
this.textColor = textColor;
this.textSize = textSize;
this.mRadius = radius;
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
mSize = (int) (paint.measureText(text, start, end) + 2 * mRadius);
//mSize就是span的宽度,span有多宽,开发者可以在这里随便定义规则
//我的规则:这里text传入的是SpannableString,start,end对应setSpan方法相关参数
//可以根据传入起始截至位置获得截取文字的宽度,最后加上左右两个圆角的半径得到span宽度
return mSize;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
int color1 = paint.getColor();//保存文字颜色
paint.setColor(this.bgColor);//设置背景颜色
paint.setAntiAlias(true); // 设置画笔的锯齿效果
RectF oval = new RectF(x, y + paint.ascent(), x + mSize , y + paint.descent());
//设置文字背景矩形,x为span其实左上角相对整个TextView的x值,y为span左上角相对整个View的y值。paint.ascent()获得文字上边缘,paint.descent()获得文字下边缘
canvas.drawRoundRect(oval, mRadius, mRadius, paint);//绘制圆角矩形,第二个参数是x半径,第三个参数是y半径
paint.setTextSize(this.textSize);
paint.setColor(textColor);
canvas.drawText(text, start, end, x + mRadius, y , paint);//绘制文字
}
}
几点需要注意的
- 字体的点击后效果,要设置背景色透明,否则会有点击后效果,影响界面
参考链接:
https://blog.csdn.net/baidu_31956557/article/details/78339071
https://www.cnblogs.com/galibujianbusana/p/6490461.html