I have been trying to add a search filter in a RecyclerView
activity. Though the search menu is on the action bar, it does not show the search results. I have given some details of the project bellow:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>`
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="@string/action_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always|collapseActionView" />
</menu>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
MenuItem searchViewItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView= (SearchView) searchViewItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);````
4.Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements Filterable {
Context context;
List<ProfileModel> myOfficerslist;
List<ProfileModel> myOfficerslistfull;
public MyAdapter(Context context, List<ProfileModel> myOfficerslist, Activity activity) {
this.context = context;
this.myOfficerslist = myOfficerslist;
this.myOfficerslistfull=new ArrayList<>(myOfficerslist);
}
@NonNull
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.profile_layout, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position) {
holder.textName.setText(myOfficerslistfull.get(position).getName());
holder.textDesignation.setText(myOfficerslistfull.get(position).getDesignation());
holder.textPosting.setText(myOfficerslistfull.get(position).getPlaceofposting());
holder.textPhone.setText(myOfficerslistfull.get(position).getCell());
holder.textEmail.setText(myOfficerslistfull.get(position).getEmail());
holder.profileimage.setImageResource(myOfficerslistfull.get(position).getProfileImage());
}
@Override
public int getItemCount() {
return myOfficerslistfull.size();
}
@Override
public Filter getFilter()
{
return myFilter;
}
Filter myFilter=new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String searchText=constraint.toString().toLowerCase().trim();
List<ProfileModel> filteredList = new ArrayList<>();
if (searchText.length()==00 || searchText.isEmpty()){
filteredList.addAll(myOfficerslistfull);
}
else
{
for (ProfileModel row : myOfficerslistfull) {
if (row.getName().toLowerCase().contains(searchText)|| (row.getDesignation().toLowerCase().contains(searchText)
||(row.getPlaceofposting().toLowerCase().contains(searchText)))) {
filteredList.add(row);
}
}
}
FilterResults filterResults=new FilterResults();
filterResults.values=filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
myOfficerslist.clear();
myOfficerslist.addAll((Collection<? extends ProfileModel>) results.values);
notifyDataSetChanged();
}
};
public static class MyViewHolder extends RecyclerView.ViewHolder{
ImageView profileimage;
TextView textName;
TextView textDesignation;
TextView textPosting;
TextView textPhone;
TextView textEmail;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
profileimage = itemView.findViewById(R.id.profilepic);
textName = itemView.findViewById(R.id.textName);
textDesignation = itemView.findViewById(R.id.textDesignation);
textPosting = itemView.findViewById(R.id.textPosting);
textPhone = itemView.findViewById(R.id.textPhone);
textEmail = itemView.findViewById(R.id.textEmail);
}
}
}
The errors found at first shot:
getItemCount()
You need to return the size of the filtered list not the size of the entire list: @Override
public int getItemCount() {
return myOfficerslist.size();
}
In onBindViewHolder()
Get the data from the filtered list not from the entire list: So change all the occurrences of myOfficerslistfull
to myOfficerslist
I guess the double 00 here is a typo, so add only a single 0
if (searchText.length()==0 || searchText.isEmpty()){