Reputation: 3591
I want to color all words starting with #, + or @. I found solutions to match words and to color substrings of a SpannableString, but it does not work right. Only the last match gets coloured the other matches stay uncoloured, but I am not able to find the error.
public static SpannableStringBuilder colorTags(Context cxt, String text){
final Pattern hashtag = Pattern.compile("#\\w+");
final Pattern at = Pattern.compile("(\\s|\\A)@(\\w+)");
final Pattern name = Pattern.compile("(\\s|\\A)\\+(\\w+)");
final SpannableStringBuilder spannable = new SpannableStringBuilder(text);
final ForegroundColorSpan at_color = new ForegroundColorSpan(cxt.getResources().getColor(R.color.orange));
final ForegroundColorSpan hash_color = new ForegroundColorSpan(cxt.getResources().getColor(R.color.light_blue));
final ForegroundColorSpan name_color = new ForegroundColorSpan(cxt.getResources().getColor(R.color.green));
final Matcher matcher = hashtag.matcher(text);
final Matcher at_matcher = at.matcher(text);
final Matcher name_matcher = name.matcher(text);
while (matcher.find()) {
spannable.setSpan(
hash_color, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
while (at_matcher.find()) {
spannable.setSpan(
at_color, at_matcher.start(), at_matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
while (name_matcher.find()) {
spannable.setSpan(
name_color, name_matcher.start(), name_matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
return spannable;
}
Upvotes: 0
Views: 470
Reputation: 31290
You need a new object for each span, or else it will be moved and end up on the last span.
while (matcher.find()) {
ForegroundColorSpan hash_color =
ForegroundColorSpan(cxt.getResources().getColor(R.color.light_blue));
spannable.setSpan( hash_color, matcher.start(), matcher.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE );
}
Same for the other loops.
Upvotes: 1