上次写了《TextView 局部文本样式设置》后,一直想整理一篇关于 SpannableString 的文章,但是一懒就忘记了,刚好最近项目中局部文字样式修改用得多,所以就趁空把文章整理出来,这是参考其他文章整理出来的,以便后续查看。
以下尺寸工具类采用《常用代码整理:尺寸工具类(SizeUtil)》
1、常用样式
SpannableString spannableString1 = new SpannableString("这是自带骚气的文本,哈1哈2哈3");
// 设置字体大小,单位为像素
spannableString1.setSpan(new AbsoluteSizeSpan(20), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体大小,第二个参数表示前面的字体大小单位为是否为dip
spannableString1.setSpan(new AbsoluteSizeSpan(20, true), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置字体大小,参数表示为默认字体大小的多少倍(如果开发者在xml中设置了android:textSize,就采用开发者设置的大小)
spannableString1.setSpan(new RelativeSizeSpan(2.5f), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体样式: NORMAL正常,BOLD粗体,ITALIC斜体,BOLD_ITALIC粗斜体
spannableString1.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 6, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体前景色(字体颜色)
spannableString1.setSpan(new ForegroundColorSpan(Color.RED), 7, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置下划线
spannableString1.setSpan(new UnderlineSpan(), 9, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置删除线
spannableString1.setSpan(new StrikethroughSpan(), 10, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置上下标
spannableString1.setSpan(new SubscriptSpan(), 13, 14, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString1.setSpan(new SuperscriptSpan(), 15, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvOne.setText(spannableString1);
2、图片替换
SpannableString spannableString2 = new SpannableString("再来看看骚气的图片替换");
Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
spannableString2.setSpan(new ImageSpan(drawable), 2, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvTwo.setText(spannableString2);
3、绘制背景
SpannableString spannableString3 = new SpannableString("这是骚气的指定文字背景绘制");
spannableString3.setSpan(new BackgroundSpan(this, 0xffff0000), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvThree.setText(spannableString3);
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.style.ReplacementSpan;
public class BackgroundSpan extends ReplacementSpan {
private Context mContext;
private int mTextColor;
private int mHeight, mTextSize, mRadius, mTextPadding, mMargin;
private RectF mTempF = new RectF();
public BackgroundSpan(Context context, int textColor) {
super();
this.mContext = context;
this.mTextColor = textColor;
this.mTextSize = SizeUtil.sp2px(mContext, 10);
this.mRadius = SizeUtil.dip2px(mContext, 3);
this.mHeight = SizeUtil.dip2px(mContext, 13);
this.mTextPadding = SizeUtil.dip2px(mContext, 2.5f);
this.mMargin = SizeUtil.dip2px(mContext, 5f);
}
/**
* 设置宽度
* 返回值就是Span替换文字后所占的宽度
*/
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
// 这里要设定文本的文字大小,不然系统会采用xml中开发者设置的android:textSize(开发者没设置就是textview的默认textSize)
// 且要注意getSize方法快于draw方法被调用
paint.setTextSize(mTextSize);
return ((int) paint.measureText(text, start, end)) + mTextPadding * 2 + SizeUtil.dip2px(mContext, 3);
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
paint.setAntiAlias(true); // 抗锯齿
paint.setDither(true); // 防抖动
// 设置画笔,绘制背景
// paint.setColor(mTextColor);
// paint.setStyle(Paint.Style.STROKE);
paint.setColor(0xff00ff00);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
/*
Paint.Style.FILL:填充内部
Paint.Style.FILL_AND_STROKE :填充内部和描边
Paint.Style.STROKE :描边
*/
mTempF.set(x, top + mMargin, x + ((int) paint.measureText(text, start, end)) + mTextPadding * 2, top + mMargin + mHeight);
canvas.drawRoundRect(mTempF, mRadius, mRadius, paint);
/*
public void drawRoundRect (RectF rect, float rx, float ry, Paint paint)
rect:RectF对象,set(float left, float top, float right, float bottom)
rx:x方向上的圆角半径
ry:y方向上的圆角半径
paint:绘制时所用画笔
*/
// 设置画笔,绘制文字
paint.setColor(mTextColor);
paint.setTextSize(mTextSize);
float textY = top + mMargin + mHeight / 2 - (paint.descent() + paint.ascent()) / 2;
canvas.drawText(text, start, end, x + mTextPadding, textY, paint);
/*
drawText(CharSequence text, int start, int end, float x, float y, Paint paint)
x:绘制文本的起始x座标
y:绘制文本的起始y座标
*/
}
}
参考文章:
1、https://blog.csdn.net/freak_csh/article/details/79276945
2、https://blog.csdn.net/u012735483/article/details/52902047