您的位置:首页 > 产品设计 > UI/UE

强大的SpannableStringBuilder并封装

2016-12-19 19:14 411 查看
TextView ClickableSpan 事件分发的两个坑

public class SpannableStringBuilderConfig {
private final Activity mActivity;
private int mTextColor;
private int mbgColor;
private int mTextSize;
private int[] mTextTypefaces;
private boolean isAddStrikethroughSpan;
private boolean isAddUnderlineSpan;
private String mImageSpanText;
private int mImageSpanRecourse;
private boolean mIsClickableSpan;
private String mStringStyle;

public SpannableStringBuilderConfig(Activity activity) {
this.mActivity = activity;
}

public SpannableStringBuilderConfig setBgColor(int bgColor) {
this.mbgColor = bgColor;
return this;
}

public SpannableStringBuilderConfig setTextColor(int textColor) {
this.mTextColor = textColor;
return this;
}

public SpannableStringBuilderConfig setTextSize(int textSize) {
this.mTextSize = textSize;
return this;
}

public SpannableStringBuilderConfig setTextTypeface(int... textTypefaces) {
this.mTextTypefaces = textTypefaces;
return this;
}

public SpannableStringBuilderConfig setStrikethroughSpan(boolean isAddStrikethroughSpan) {
this.isAddStrikethroughSpan = isAddStrikethroughSpan;
return this;
}

public SpannableStringBuilderConfig setUnderlineSpan(boolean isAddUnderlineSpan) {
this.isAddUnderlineSpan = isAddUnderlineSpan;
return this;
}

public SpannableStringBuilderConfig setImageSpan(String imageSpanText, int imageSpanRecourse) {
this.mImageSpanText = imageSpanText;
this.mImageSpanRecourse = imageSpanRecourse;
return this;
}
public SpannableStringBuilderConfig setClickableSpan(boolean isClickableSpan) {
this.mIsClickableSpan = isClickableSpan;
return this;
}

public SpannableStringBuilderConfig setSpannable (String stringStyle) {
this.mStringStyle = stringStyle;
return this;
}

public SpannableStringBuilder getKeyWordSpan(String patterStr, String keyword) {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder("");
if (TextUtils.isEmpty(patterStr)) return stringBuilder;
if (TextUtils.isEmpty(keyword)) return stringBuilder.append(patterStr);
try {
SpannableStringBuilder append = stringBuilder.append(patterStr);
dealPattern(append, keyword, 0);
dealImagePattern(append, keyword, 0);
} catch (Exception e) {
e.printStackTrace();
}
return stringBuilder;
}

/**
* 对spanableString进行正则判断,如果符合要求,则将内容变色
*
* @param spannableString
* @param keyword
* @param start
* @throws Exception
*/
private void dealPattern(SpannableStringBuilder spannableString, String keyword, int start) throws Exception {
Pattern patten = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
Matcher matcher = patten.matcher(spannableString);
while (matcher.find()) {
String key = matcher.group();
// 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归
if (matcher.start() < start) {
continue;
}
// 计算该内容的长度,也就是要替换的字符串的长度
int end = matcher.start() + key.length();
//设置前景色span
if (mTextColor != 0) {
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(mTextColor);
spannableString.setSpan(foregroundColorSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (mbgColor != 0) {
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(mbgColor);
spannableString.setSpan(backgroundColorSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (mTextSize != 0) {
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(mTextSize);
spannableString.setSpan(absoluteSizeSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

if (mTextTypefaces != null && mTextTypefaces.length > 0) {
for (int typeface : mTextTypefaces) {
StyleSpan styleSpan = new StyleSpan(typeface);
spannableString.setSpan(styleSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}

if (isAddStrikethroughSpan) {
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString.setSpan(strikethroughSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

if (isAddUnderlineSpan) {
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

if (mIsClickableSpan){
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(mActivity,"点击",Toast.LENGTH_SHORT).show();
}

@Override
public void updateDrawState(TextPaint ds) {
// ds.setColor(getResources().getColor(R.color.link_color));
// ds.setUnderlineText(false);
}
};
spannableString.setSpan(clickableSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

if (end < spannableString.length()) {
// 如果整个字符串还未验证完,则继续。。
dealPattern(spannableString, keyword, end);
}
break;
}
}

private void dealImagePattern(SpannableStringBuilder spannableString, String keyword, int start) {
if (TextUtils.isEmpty(mImageSpanText) || keyword.equals(mImageSpanText)
|| mImageSpanRecourse == 0) return;
Pattern patten = Pattern.compile(mImageSpanText, Pattern.CASE_INSENSITIVE);
Matcher matcher = patten.matcher(spannableString);
while (matcher.find()) {
String key = matcher.group();
// 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归
if (matcher.start() < start) {
continue;
}
// 计算该内容的长度,也就是要替换的字符串的长度
int end = matcher.start() + key.length();
ImageSpan imageSpan = new ImageSpan(mActivity, mImageSpanRecourse);
spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (end < spannableString.length()) {
// 如果整个字符串还未验证完,则继续。。
dealImagePattern(spannableString, keyword, end);
}
break;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: