SpannableString其实和String一样,都是一种字符串类型,SpannableString可以直接作为TextView的显示文本,不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示,重要的是可以指定设置的区间,也就是为字符串指定下标区间内的子字符串设置格式。
setSpan(Object what, int start, int end, int flags)方法需要用户输入四个参数,what表示设置的格式是什么,可以是前景色、背景色也可以是可点击的文本等等,start表示需要设置格式的子字符串的起始下标,同理end表示终了下标,flags属性就有意思了,共有四种属性:
Spanned.SPAN_INCLUSIVE_EXCLUSIVE 从起始下标到终了下标,包括起始下标
Spanned.SPAN_INCLUSIVE_INCLUSIVE 从起始下标到终了下标,同时包括起始下标和终了下标
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 从起始下标到终了下标,但都不包括起始下标和终了下标
Spanned.SPAN_EXCLUSIVE_INCLUSIVE 从起始下标到终了下标,包括终了下标
SpannableString的setSpan()方法可以同时使用多个,实现多种效果叠加。
span的种类:
ForegroundColorSpan:前景色
BackgroundColorSpan:背景色
ClickableSpan:抽象类,可点击效果,重写onClick方法响应点击事件
URLSpan:超链接
MaskFilterSpan:EmbossMaskFilter浮雕效果,BlurMaskFilter模糊效果
RelativeSpan:文字相对大小
AbsoluteSpan:文字绝对大小
ScaleXSpan:x轴缩放
styleSpan:文字样式
TypefaceSpan:文字字体类型
TextApearanceSpan:文字外貌
UnderlineSpan:下划线
StrikeThroughSpan:删除线
SuperscriptSpan:上标
SubscriptSpan:下标
ImageSpan:图片
这些Span能够很好地帮助我们润色文字
实现图片文字环绕效果
/**
* @author 付影影
* @desc 文字嵌套图片
* @date 2019/9/27
*/
public class TextViewHelper {
/**
* @param context 上下文
* @param drawable 嵌套图片
* @param msg 商品名称
* @return
*/
public static SpannableString setLeftImage(Context context, int drawable, String msg) {
SpannableString spannableString = new SpannableString(" " + msg);
Drawable rightDrawable = context.getResources().getDrawable(drawable);
rightDrawable.setBounds(0, 0, rightDrawable.getIntrinsicWidth(), rightDrawable.getIntrinsicHeight());
spannableString.setSpan(new MyImageSpan(rightDrawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;
}
}
/**
* @author 付影影
* @desc 为了让文字和图片居中对齐
* @date 2019/9/27
*/
public class MyImageSpan extends ImageSpan {
public MyImageSpan(Context context, Bitmap bitmap) {
super(context, bitmap);
}
public MyImageSpan(Context context, Bitmap bitmap, int verticalAlignment) {
super(context, bitmap, verticalAlignment);
}
public MyImageSpan(Drawable drawable) {
super(drawable);
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
try {
Drawable d = getDrawable();
Rect rect = d.getBounds();
if (fm != null) {
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.bottom - fmPaint.top;
int drHeight = rect.bottom - rect.top;
int top = drHeight / 2 - fontHeight / 4;
int bottom = drHeight / 2 + fontHeight / 4;
fm.ascent = -bottom;
fm.top = -bottom;
fm.bottom = top;
fm.descent = top;
}
return rect.right;
} catch (Exception e) {
return 20;
}
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
try {
Drawable d = getDrawable();
canvas.save();
int transY = 0;
transY = ((bottom - top) - d.getBounds().bottom) / 2 + top;
canvas.translate(x, transY);
d.draw(canvas);
canvas.restore();
} catch (Exception e) {
}
}
}
调用
TextView shopName = helper.getView(R.id.shop_name);
if (prdlist.getGoodsType() == 1) {
SpannableString spannableString = TextViewHelper.setLeftImage(mContext, R.drawable.icon_outlands_goods, prdlist.getName());
shopName.setText(spannableString);
} else {
shopName.setText(prdlist.getName());
}
结果