How To Highlight Filtered Text In Recyclerview When Using Searchview Widget
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"