Skip to content Skip to sidebar Skip to footer

Highlight Searched Text In Listview Items

I have a ListView and i am using a custom adapter to show data. Now i want to change searched text letter colour as in above screen shot. Here is the code for SearchView @Overrid

Solution 1:

I assume that you have a custom Adapter with getCount() and getView() implemented and already filtering items, and you just need the bold part.

To achieve that, you need to use a SpannableString, which is basically text with markup attached. For example, a TextAppearanceSpan can be used to change typeface, font style, size, and color.

So, you should update your adapter's getView() to change the part where you use textView.setText() into something more or less like this:

Stringfilter= ...;
StringitemValue= ...;

intstartPos= itemValue.toLowerCase(Locale.US).indexOf(filter.toLowerCase(Locale.US));
intendPos= startPos + filter.length();

if (startPos != -1) // This should always be true, just a sanity check
{
    Spannablespannable=newSpannableString(itemValue);
    ColorStateListblueColor=newColorStateList(newint[][] { newint[] {}}, newint[] { Color.BLUE });
    TextAppearanceSpanhighlightSpan=newTextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);

    spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.setText(spannable);
}
else
    textView.setText(itemValue);

Solution 2:

Android Search Highlight Example [Case Insensitive Order]

1.Search:[Highlight Specific Word]

publicstatic SpannableStringBuilder highlightSearchText(SpannableStringBuilder fullText, String searchText) {

    if (searchText.length() == 0) return fullText;

    SpannableStringBuilderwordSpan=newSpannableStringBuilder(fullText);
    Patternp= Pattern.compile(searchText, Pattern.CASE_INSENSITIVE);
    Matcherm= p.matcher(fullText);
    while (m.find()) {

        intwordStart= m.start();
        intwordEnd= m.end();

        setWordSpan(wordSpan, wordStart, wordEnd);

    }

    return wordSpan;
}

2.Search:[Highlight Full Word]

publicstatic SpannableStringBuilder highlightSearchText(SpannableStringBuilder fullText, String searchText) {

    if (searchText.length() == 0) return fullText;

    finalStringsearchBoundary=" \n()।.,;?-+!";
    char[] boundaries = searchBoundary.toCharArray();

    // highlight search textif (isNotEquals(searchText, boundaries)) {

        SpannableStringBuilderwordSpan=newSpannableStringBuilder(fullText);
        Patternp= Pattern.compile(searchText, Pattern.CASE_INSENSITIVE);
        Matcherm= p.matcher(fullText);
        while (m.find()) {

            intwordStart= m.start();
            while (wordStart >= 0 && isNotEquals(fullText.charAt(wordStart), boundaries)) {
                --wordStart;
            }
            wordStart = wordStart + 1;

            intwordEnd= m.end();
            while (wordEnd < fullText.length() && isNotEquals(fullText.charAt(wordEnd), boundaries)) {
                ++wordEnd;
            }

            setWordSpan(wordSpan, wordStart, wordEnd);

        }

        return wordSpan;

    } else {
        return fullText;
    }
}

privatestaticbooleanisNotEquals(String searchText, char[] boundaries) {
    for (char boundary : boundaries) {
        booleanequals= searchText.equals(String.valueOf(boundary));
        if (equals) returnfalse;
    }
    returntrue;
}

privatestaticbooleanisNotEquals(char charAt, char[] boundaries) {
    for (char boundary : boundaries) {
        booleanisEquals= charAt == boundary;
        if (isEquals) returnfalse;
    }
    returntrue;
}

Common Method:

privatestaticvoidsetWordSpan(SpannableStringBuilder wordSpan, int wordStart, int wordEnd) {
    // Now highlight based on the word boundaries
    ColorStateList redColor = new ColorStateList(newint[][]{newint[]{}}, newint[]{0xffa10901});
    TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);

    wordSpan.setSpan(highlightSpan, wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    wordSpan.setSpan(new BackgroundColorSpan(0xFFFCFF48), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    wordSpan.setSpan(new RelativeSizeSpan(1.25f), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

Solution 3:

You can use the CodeView library to implement this feature, all you need is to create 2 variables in the adapter to store the pattern of search result and the color of highlighting,

private Pattern syntaxPattern;
privateColorhighlightColor= Color.MAGENTA;

and create a setter in the adapter for pattern and color

publicvoidupdateSyntaxPattern(Pattern pattern) {
    syntaxPattern = pattern;
    notifyDataSetChanged();
}

then in getView method for ArrayAdapter or ViewHolder in RecyclerAdapter you need to add this pattern to the CodeView instance and remove the old patterns (from the last search result)

if(syntaxPattern != null) {
    codeView.resetSyntaxPatternList();
    codeView.addSyntaxPattern(syntaxPattern, highlightColor);
}

Now in SearchView onQueryTextSubmit or onQueryTextChange, depend on when you want the highlighter to work you will choose one of them you need to make the pattern from the search result and set it to the adapter

Patternpattern= Pattern.compile(query);
adapter.updateSyntaxPattern(pattern);

It will work exactly as you want

enter image description here

Post a Comment for "Highlight Searched Text In Listview Items"