Suraj's answer is great and works, but has 2 missing components. First, it will not highlight the first word (as Rany commented) and second, it does not ignore case so searching for "test"
in this String: "This is a Test"
will not find anything.
This is my updated answer which resolves both of those via a passed argument and also adds in alpha in case you want to use a custom color for your highlighting. Note that the overloaded first method is a sample for how to return what the previous method did other than the first item being selected.
/**
* Use this method to get the same return as the previous method
*/
public static SpannableString buildHighlightString(String originalText, String textToHighlight){
return buildHighlightString(originalText, textToHighlight, false, Color.YELLOW, 1.0F);
}
/**
* Build a spannable String for use in highlighting text colors
*
* @param originalText The original text that is being highlighted
* @param textToHighlight The text / query that determines what to highlight
* @param ignoreCase Whether or not to ignore case. If true, will ignore and "test" will have
* the same return as "TEST". If false, will return an item as highlighted
* only if it matches it case specficic.
* @param highlightColor The highlight color to use. IE {@link Color#YELLOW} || {@link Color#BLUE}
* @param colorAlpha Alpha to adjust how transparent the color is. 1.0 means it looks exactly
* as it should normally where as 0.0 means it is completely transparent and
* see-through. 0.5 means it is 50% transparent. Useful for darker colors
*/
public static SpannableString buildHighlightString(String originalText, String textToHighlight,
boolean ignoreCase, @ColorInt int highlightColor,
@FloatRange(from = 0.0, to = 1.0) float colorAlpha){
SpannableString spannableString = new SpannableString(originalText);
if (TextUtils.isEmpty(originalText) || TextUtils.isEmpty(textToHighlight)) {
return spannableString;
}
String lowercaseOriginalString = originalText.toLowerCase();
String lowercaseTextToHighlight = textToHighlight.toLowerCase();
if(colorAlpha < 1){
highlightColor = ColorUtils.setAlphaComponent(highlightColor, ((int)(255*colorAlpha)));
}
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = (ignoreCase)
? lowercaseOriginalString.indexOf(lowercaseTextToHighlight)
: originalText.indexOf(textToHighlight);
while (indexOfKeyword != -1) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(highlightColor), indexOfKeyword,
indexOfKeyword + (textToHighlight.length()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = (ignoreCase)
? lowercaseOriginalString.indexOf(lowercaseTextToHighlight, (indexOfKeyword) + textToHighlight.length())
: originalText.indexOf(textToHighlight, (indexOfKeyword) + textToHighlight.length());
}
return spannableString;
}