上图包含以下各项操作:
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;
/**
* # ******************************************************************
* # ClassName: TextSpannableUtils
* # Description: TextView设置Spannable风格的工具类
* # Author: atwang
* # Version: Ver 1.0
* # Create Date 2021/10/12 14:28
* # ******************************************************************
* @author atwang
*/
public class TextSpannableUtils {
private static ClickableSpanCallBack mClickableSpanCallBack;
public TextSpannableUtils() {
}
/**
* textView内容中的关键字设置颜色
* @param content
* @param keyWord
* @param textView
*/
public static void setPartColorSpan(String content, String keyWord, int resColorId, TextView textView) {
int start = content.indexOf(keyWord);
int end = start + keyWord.length();
if (end!=0&&start!=-1){
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(content);
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(resColorId);
builder.setSpan(foregroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder);
}
}
/**
* textView内容中的关键字设置颜色
* @param keyWord 关键数据
* @param unit 单位
* @param textView 控件
*/
public static void setPartTextColor(String keyWord, String unit, int resColorId, TextView textView) {
int start = 0;
int end = start + keyWord.length();
String content = keyWord + unit;
if (end != 0){
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(content);
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(resColorId);
builder.setSpan(foregroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder);
}
}
/**
* textView内容中的关键字设置背景色
* @param content
* @param keyWord
* @param textView
*/
public static void setPartBackgroundColor(String content, String keyWord, int resColorId, TextView textView) {
int start = content.indexOf(keyWord);
int end = start + keyWord.length();
if (end!=0&&start!=-1){
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(content);
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(resColorId);
builder.setSpan(backgroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder);
}
}
/**
* textView内容中的关键字设置大小
* @param content 关键数据
* @param keyWord 单位
* @param textView 控件
*/
public static void setPartTextSize( String content, String keyWord, int size, TextView textView) {
int start = content.indexOf(keyWord);
int end = start + keyWord.length();
if (end!=0&&start!=-1){
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(content);
//第二个参数boolean dip,如果为true,表示前面的字体大小单位为dip,否则为像素
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(size,true);
builder.setSpan(absoluteSizeSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder);
}
}
/**
* textView内容中的关键字设置大小
* @param content 关键数据
* @param keyWord 单位
* @param textView 控件
*/
public static void setPartRelativeSize( String content, String keyWord, float multiple, TextView textView) {
int start = content.indexOf(keyWord);
int end = start + keyWord.length();
if (end!=0&&start!=-1){
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(content);
//参数表示设置关键字大小为默认字体大小的多少倍
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(multiple);
builder.setSpan(relativeSizeSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder);
}
}
/**
* textView内容设置斜体
* @param content
* @param textView
*/
public static void setPartItalic(String content, TextView textView){
SpannableString sp = new SpannableString(content);
sp.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, content.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
textView.setText(sp);
}
/**
* textView内容中的关键字设置斜体
* @param content
* @param keyWord
* @param textView
*/
public static void setPartItalic(String content, String keyWord, TextView textView){
SpannableStringBuilder builder = new SpannableStringBuilder(content);
int start = content.indexOf(keyWord);
if (start < 0) {
if (content.length() > 0) {
textView.setText(content);
} else {
textView.setText("");
}
return;
}
int end = start + keyWord.length();
builder.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (textView != null) {
textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
textView.setText(builder);
}
}
/**
* textView内容添加下划线
* @param textView
*/
public static void setPartUnderline(TextView textView){
//下划线/抗锯齿
textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG|Paint.ANTI_ALIAS_FLAG);
}
/**
* textView内容中的关键字添加下划线
* @param content
* @param keyWord
* @param textView
*/
public static void setPartUnderline(String content, String keyWord, TextView textView){
SpannableStringBuilder builder = new SpannableStringBuilder(content);
int start = content.indexOf(keyWord);
if (start < 0) {
if (content.length() > 0) {
textView.setText(content);
} else {
textView.setText("");
}
return;
}
int end = start + keyWord.length();
builder.setSpan(new StyleSpan( Paint.UNDERLINE_TEXT_FLAG),start ,end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
if (textView != null) {
textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
textView.setText(builder);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
/**
* textView内容添加删除线
* @param textView
*/
public static void setPartDeleteLine(TextView textView){
//删除线/抗锯齿
textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG|Paint.ANTI_ALIAS_FLAG);
}
/**
* textView内容添加删除线
* @param content
* @param textView
*/
public static void setPartDeleteLine(String content, TextView textView){
SpannableString sp = new SpannableString(content);
sp.setSpan(new StrikethroughSpan(), 0, content.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sp);
}
/**
* textView内容中的关键字添加删除线
* @param content
* @param keyWord
* @param textView
*/
public static void setPartDeleteLine(String content, String keyWord, TextView textView){
SpannableStringBuilder builder = new SpannableStringBuilder(content);
int start = content.indexOf(keyWord);
if (start < 0) {
if (content.length() > 0) {
textView.setText(content);
} else {
textView.setText("");
}
return;
}
int end = start + keyWord.length();
builder.setSpan(new StrikethroughSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (textView != null) {
textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
textView.setText(builder);
}
}
/**
* textView内容中的关键字添加超链接
* @param content
* @param keyWord
* @param url
* @param textView
*/
public static void setPartUrlClick(String content, String keyWord, String url, TextView textView) {
SpannableStringBuilder builder = new SpannableStringBuilder(content);
int start = content.indexOf(keyWord);
if (start < 0) {
if (content.length() > 0) {
textView.setText(content);
} else {
textView.setText("");
}
return;
}
int end = start + keyWord.length();
builder.setSpan(new URLSpan(url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new StyleSpan(Paint.UNDERLINE_TEXT_FLAG), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
if (textView != null) {
textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
textView.setText(builder);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
/**
* textView内容中的关键字添加点击事件
* @param content
* @param keyWord
* @param resColorId
* @param textView
*/
public static void setPartClick(String content, String keyWord, int resColorId, TextView textView) {
SpannableStringBuilder builder = new SpannableStringBuilder(content);
int start = content.indexOf(keyWord);
if (start < 0) {
if (content.length() > 0) {
textView.setText(content);
} else {
textView.setText("");
}
return;
}
int end = start + keyWord.length();
builder.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
if (mClickableSpanCallBack != null) {
mClickableSpanCallBack.onClick();
avoidHintColor(widget);
}
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
}
}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new ForegroundColorSpan(resColorId), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new StyleSpan(Paint.UNDERLINE_TEXT_FLAG), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
if (textView != null) {
textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
textView.setText(builder);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
/**
* 设置选中文字背景色
* @param view
*/
private static void avoidHintColor(View view){
if(view instanceof TextView) {
((TextView)view).setHighlightColor(Color.TRANSPARENT);
}
}
public void setClickableSpanCallBack(ClickableSpanCallBack clickableSpanCallBack) {
mClickableSpanCallBack = clickableSpanCallBack;
}
public interface ClickableSpanCallBack{
void onClick();
}
}