很多 APP 都有下面的效果:
这样的效果就是用 SpannableStringBuilder 实现的,下面就了解 SpannableStringBuilder 的简单使用以及实现上面的效果。
SpannableString、SpannableStringBuilder与String的关系
SpannableString、SpannableStringBuilder 基本上与 String 差不多,也是用来存储字符串。但它俩有一个 SetSpan() 方法,可以设置各种样式,比如设置部分字体颜色、大小、下划线、将文字替换为图片等等。
SpannableString 与 SpannableStringBuilder区别
SpannableString 像一个 String 一样,传入一个 String 之后再无法更改 String 的内容,也无法拼接多个 SpannableString ;
而 SpannableStringBuilder 则更像是 StringBuilder ,它可以通过其 append() 方法来拼接多个 String。
SpannableStringBuilder 简单使用
设置部分文字颜色,如图:
代码为( tv_id 为一个 TextView):
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
//设置字体颜色
ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#FF0090FF"));
spannableString.setSpan(colorSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setText(spannableString);
设置字体大小,如图:
代码为:
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(20);
spannableString.setSpan(absoluteSizeSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setText(spannableString);
设置字体背景颜色,如图:
代码为:
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.parseColor("#009ad6"));
spannableString.setSpan(bgColorSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setText(spannableString);
设置粗体、斜体,如图:
代码为:
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);//粗体
spannableString.setSpan(styleSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
StyleSpan styleSpan2 = new StyleSpan(Typeface.ITALIC);//斜体
spannableString.setSpan(styleSpan2, 4, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
StyleSpan styleSpan3 = new StyleSpan(Typeface.BOLD_ITALIC);//粗斜体
spannableString.setSpan(styleSpan3, 7, spannableString.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setText(spannableString);
设置删除线、下划线如图:
代码为:
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
//删除线
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString.setSpan(strikethroughSpan, 0, 7, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//下划线
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan, 8, spannableString.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setText(spannableString);
文字替换为图片并设置图片大小,如图:
代码为:
//25dp转化为px
float dp = 25;
final float scale = getResources().getDisplayMetrics().density;
//由25dp转化来的px
int px = (int) (dp * scale + 0.5f);
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
//添加图片
Drawable drawable = getResources().getDrawable(R.drawable.face_1);
drawable.setBounds(0, 0, px, px);
ImageSpan imageSpan1 = new ImageSpan(drawable);
spannableString.setSpan(imageSpan1, spannableString.length() - 1, spannableString.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setText(spannableString);
部分文字点击事件,如图:
代码如下:
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(Color.parseColor("#FF0090FF"));//设置颜色
ds.setUnderlineText(false);//去掉下划线
}
@Override
public void onClick(View view) {
ToastUtil.show(mContext, "点击小明");
}
};
spannableString.setSpan(clickableSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setHighlightColor(Color.TRANSPARENT); //设置点击后的颜色为透明,否则会一直出现高亮
tv_id.setText(spannableString);
tv_id.setMovementMethod(LinkMovementMethod.getInstance());//触发点击事件
这样 SpannableStringBuilder 的简单使用就讲完了,下面来看一下组合使用,实现最开始的效果图。
SpannableStringBuilder 组合使用
首先设置小明的颜色与点击事件,其次设置小红的颜色与点击事件,最后设置内容颜色与点击事件并将最后的句号替换为图片。
代码如下:
//25dp转化为px
float dp = 25;
final float scale = getResources().getDisplayMetrics().density;
//由25dp转化来的px
int px = (int) (dp * scale + 0.5f);
SpannableStringBuilder spannableString = new SpannableStringBuilder();
spannableString.append("小明回复小红:你在干嘛呀。");
/**
* 设置小明
* 颜色和点击事件
*/
//设置字体颜色
ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#FF0090FF"));
spannableString.setSpan(colorSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//点击事件
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(Color.parseColor("#FF0090FF"));//设置颜色
ds.setUnderlineText(false);//去掉下划线
}
@Override
public void onClick(View view) {
ToastUtil.show(mContext, "点击小明");
}
};
spannableString.setSpan(clickableSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
/**
* 设置小红
* 颜色和点击事件
*/
//设置字体颜色
ForegroundColorSpan colorSpan1 = new ForegroundColorSpan(Color.parseColor("#FF0090FF"));
spannableString.setSpan(colorSpan1, 4, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//点击事件
ClickableSpan clickableSpan1 = new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(Color.parseColor("#FF0090FF"));//设置颜色
ds.setUnderlineText(false);//去掉下划线
}
@Override
public void onClick(View view) {
ToastUtil.show(mContext, "点击小红");
}
};
spannableString.setSpan(clickableSpan1, 4, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
/**
* 内容最后添加图片
* 将文字最后的。替换为了图片
*/
Drawable drawable = getResources().getDrawable(R.drawable.face_1);
drawable.setBounds(0, 0, px, px);
ImageSpan imageSpan1 = new ImageSpan(drawable);
spannableString.setSpan(imageSpan1, spannableString.length() - 1, spannableString.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
/**
* 内容点击事件
*/
ClickableSpan clickableSpan2 = new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(Color.parseColor("#FF151515"));//设置颜色
ds.setUnderlineText(false);//去掉下划线
}
@Override
public void onClick(View view) {
ToastUtil.show(mContext, "点击内容");
}
};
spannableString.setSpan(clickableSpan2, 7, spannableString.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv_id.setHighlightColor(Color.TRANSPARENT); //设置点击后的颜色为透明,否则会一直出现高亮
tv_id.setText(spannableString);
tv_id.setMovementMethod(LinkMovementMethod.getInstance());
这样便完成了开始的效果图。