Source:
private Spannable highlightSearches(String displayString, String backgroundString) { Spannable raw = new SpannableString(displayString); String normalizedDisplayString = StringUtils.normalize(displayString); if (searchTerms == null) { return raw; } BackgroundColorSpan[] spans=raw.getSpans(0,raw.length(), BackgroundColorSpan.class); for (BackgroundColorSpan span : spans) { raw.removeSpan(span); } Vector<int[]> matches = new Vector<int[]>(); boolean matched = false; for (String searchText : searchTerms) { if ("".equals(searchText)) { continue;} int index = TextUtils.indexOf(normalizedDisplayString, searchText); while (index >= 0) { raw.setSpan(new BackgroundColorSpan(this.getContext().getResources().getColor(R.color.search_highlight)), index, index + searchText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); matches.add(new int[] {index, index + searchText.length() } ); index=TextUtils.indexOf(raw, searchText, index + searchText.length()); matched = true; } } if(backgroundString != null) { backgroundString = backgroundString.trim() + " "; backgroundString = StringUtils.normalize(backgroundString).trim() + " "; for (String searchText : searchTerms) { if ("".equals(searchText)) { continue;} int curStart = 0; int curEnd = backgroundString.indexOf(" ", curStart); while(curEnd != -1) { boolean skip = matches.size() != 0; for(int[] textMatch : matches) { if(curStart < textMatch[0] && curEnd <= textMatch[0]) { skip = false; } else if(curStart >= textMatch[1] && curEnd > textMatch[1]) { skip = false; } } if(!skip) { if(StringUtils.fuzzyMatch(backgroundString.substring(curStart, curEnd), searchText)) { raw.setSpan(new BackgroundColorSpan(this.getContext().getResources().getColor(R.color.search_fuzzy_match)), curStart, curEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } curStart = curEnd + 1; curEnd = backgroundString.indexOf(" ", curStart); } } } return raw; }

Target:
private Spannable highlightSearches(String displayString, String backgroundString) { Spannable raw = new SpannableString(displayString); String normalizedDisplayString = StringUtils.normalize(displayString); if (searchTerms == null) { return raw; } BackgroundColorSpan[] spans=raw.getSpans(0,raw.length(), BackgroundColorSpan.class); for (BackgroundColorSpan span : spans) { raw.removeSpan(span); } Vector<int[]> matches = new Vector<int[]>(); boolean matched = false; for (String searchText : searchTerms) { if ("".equals(searchText)) { continue;} int index = TextUtils.indexOf(normalizedDisplayString, searchText); while (index >= 0) { raw.setSpan(new BackgroundColorSpan(this.getContext().getResources().getColor(R.color.search_highlight)), index, index + searchText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); matches.add(new int[] {index, index + searchText.length() } ); index=TextUtils.indexOf(raw, searchText, index + searchText.length()); matched = true; } } if(backgroundString != null) { backgroundString = StringUtils.normalize(backgroundString).trim() + " "; for (String searchText : searchTerms) { if ("".equals(searchText)) { continue;} int curStart = 0; int curEnd = backgroundString.indexOf(" ", curStart); while(curEnd != -1) { boolean skip = matches.size() != 0; for(int[] textMatch : matches) { if(curStart < textMatch[0] && curEnd <= textMatch[0]) { skip = false; } else if(curStart >= textMatch[1] && curEnd > textMatch[1]) { skip = false; } } if(!skip) { if(StringUtils.fuzzyMatch(backgroundString.substring(curStart, curEnd), searchText)) { raw.setSpan(new BackgroundColorSpan(this.getContext().getResources().getColor(R.color.search_fuzzy_match)), curStart, curEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } curStart = curEnd + 1; curEnd = backgroundString.indexOf(" ", curStart); } } } return raw; }