Skip to content Skip to sidebar Skip to footer

How To Highlight Filtered Text In Recyclerview When Using Searchview Widget

How to highlight search text result in RecyclerView. I found some posts regarding Spannable TextView, but not sure where to implement in my case. Appreciate you can look and assis

Solution 1:

As per accepted answer indexOf() is not working in case of string value is "Mumbai" same occurrences inside string. So here I have used "Pattern" and "Matcher" class to make it work. Also, I have added ".toLowerCase()" to make string with same case and query work on string as ignore case. If you no need of ignore case of query string, You can remove .toLowerCase() from this code snippet

SpannableStringBuildersb=newSpannableStringBuilder(desc);
        Patternword= Pattern.compile(query.toLowerCase());
        Matchermatch= word.matcher(desc.toLowerCase());

        while (match.find()) {
            ForegroundColorSpanfcs=newForegroundColorSpan(
                    ContextCompat.getColor(context, R.color.colorPrimary)); //specify color here
                sb.setSpan(fcs, match.start(), match.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        }
        viewHolders.text_view_title.setText(sb);

Solution 2:

change your adapter to

publicclassMyRecAdapterextendsRecyclerView.Adapter<MyRecAdapter.VH> {
        public List<Post> parkingList;        
        public Context context;
        ArrayList<Post> mCountryModel;  
        String searchText;
        
        publicMyRecAdapter(List<Post> parkingList, Context context) {
            this.parkingList = parkingList;
            this.context = context;
        }        
        @Overridepublic MyRecAdapter.VH onCreateViewHolder(ViewGroup parent, int viewType) {
            returnnewMyRecAdapter.VH(LayoutInflater.from(parent.getContext()).inflate(R.layout.mycardview, parent, false));
        }        
        @OverridepublicvoidonBindViewHolder(MyRecAdapter.VH holder, int position) {       
                Stringtitle= parkingList.get(position).getPostTitle();
                Stringdesc= parkingList.get(position).getPostSubTitle();
                
                holder.t1.setText(Html.fromHtml(title));                    
                if(searchText.length()>0){
                    //color your text hereintindex= desc.indexOf(searchText);
                    while(index>0){
                       SpannableStringBuildersb=newSpannableStringBuilder(desc);
                       ForegroundColorSpanfcs=newForegroundColorSpan(Color.rgb(158, 158, 158)); //specify color here
                       sb.setSpan(fcs, index, index+searchText.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
                        index = desc.indexOf(searchText,index+1);
                       
                    }
                    holder.t2.setText(sb);  
                    
                }else{
                holder.t2.setText(Html.fromHtml(desc));  
                }
                      
        }        
        @OverridepublicintgetItemCount() {
            return parkingList.size();
        }        
        publicclassVHextendsRecyclerView.ViewHolder {
            TextView t1, t2;        
            publicVH(View view) {
                super(view);        
                t1 = (TextView) view.findViewById(R.id.list_title);
                t2 = (TextView) view.findViewById(R.id.list_desc);        
            }        
        }          
        publicvoidsetFilter(List<Post> countryModels,String searchText) {
            mCountryModel = newArrayList<>();
            mCountryModel.addAll(countryModels);        
            this.searchText = searchText;
            notifyDataSetChanged();        
        }

    }

and set onQueryTextChange to

@Overridepublic boolean onQueryTextChange(String newText) {        

            final List<Post> filteredModelList = filter(list, newText);        
            if (filteredModelList.size() > 0) {        
                myRecAdapter.setFilter(filteredModelList,newText);
                returntrue;
            } else {
                Toast.makeText(Chapter1.this, "Not Found", Toast.LENGTH_SHORT).show();
                returnfalse;
            }
        }     

Solution 3:

Use inside on Bind view holder in Adapter class

String title1 = Itemlist.get(position).getN_stall_name().toLowerCase(Locale.getDefault());
            holder.title.setText(Itemlist.get(position).getN_stall_name());

if (title1.contains(searchText)) {
                int startPos = title1.indexOf(searchText);
                int endPos = startPos + searchText.length();
                Spannable spanString = Spannable.Factory.getInstance().newSpannable(holder.title.getText());
                spanString.setSpan(new ForegroundColorSpan(Color.RED), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                holder.title.setText(spanString);
            }

And now create public method in Adapter class

publicvoidupdateList(List<GetShop> list, String searchText) {
            Itemlist = newArrayList<>();
            Itemlist.addAll(list);
            this.searchText = searchText;
            notifyDataSetChanged();
        }

Search view listener use inside Activity where you use search view

SearchView searchview=findviewbyid(R.id.searchview);
    searchview.setOnQueryTextListener(newSearchView.OnQueryTextListener() {
                @OverridepublicbooleanonQueryTextSubmit(String query) {
                    returnfalse;
                }
                @OverridepublicbooleanonQueryTextChange(String newText) {
                    newText = newText.toLowerCase();
                    ArrayList<GetShop> newList = newArrayList<>();
                    for (GetShop userInfo : items) {
                        Stringtype = userInfo.getN_stall_name().toLowerCase();
                        if (type.contains(newText)) {
                            newList.add(userInfo);
                        }
                    }
                    disp_adapter.updateList(newList, newText);
                    returntrue;
                }
            });

Solution 4:

while(index>**-1**){
                   SpannableStringBuilder sb = new SpannableStringBuilder(desc);
                   ForegroundColorSpan fcs = new ForegroundColorSpan(Color.rgb(158, 158, 158)); //specify color here
                   sb.setSpan(fcs, index, **index** + searchText.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
                    index = desc.indexOf(searchText,index+1);

                }

A little add-on to the previous answer , you should check index >-1 instead, else the first text wont be highlighted. For setSpan , the int end should be your index + searchText.length().

Solution 5:

/**
 * Kotlin Code
 * highlight the backgroundText
 * searchText -> pass the hightlight that appear in background
 * name -> actual string name
 * textView -> append the data to widget.
 */privatefunhighlightText(
    searchText: String,
    name: String,
    textView: TextView
) {
    if (searchText.isNotEmpty() && name.contains(searchText)) {
        val sb = SpannableStringBuilder(name)
        var index: Int = name.lowercase().indexOf(searchText.lowercase())
        while (index >= 0 && index < name.length) {
            val fcs = BackgroundColorSpan(Color.rgb(0, 200, 200)) //specify color here
            sb.setSpan(
                fcs,
                index,
                index + searchText.length,
                Spannable.SPAN_INCLUSIVE_INCLUSIVE
            )
            index = name.indexOf(searchText, index + 1)
        }
        textView.text = sb
    } else {
        textView.text = name
    }
}

Post a Comment for "How To Highlight Filtered Text In Recyclerview When Using Searchview Widget"