Search code examples
androidandroid-recyclerviewandroid-filterable

My Filterable Adapter is finding results but not displaying


I have implemented Filterable in my RecyclerView.Adapter<> to search for specific locations by either their name or district. I log the result in every iteration in the performFiltering() method in the Filter like so where filteredLocationList is a class variable:

private class LocationsAdapter extends RecyclerView.Adapter<LocationsAdapter.MyViewHolder> implements Filterable {
    private List<Location> locationList;
    private List<Location> filteredLocationList;

    LocationsAdapter(List<Location> locationList) {
        this.locationList = locationList;
        this.filteredLocationList = locationList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.view_location_row, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Location location = locationList.get(position);
        holder.name.setText(location.locName);
        holder.district.setText(location.locDistrict);

    }

    @Override
    public int getItemCount() {
        return filteredLocationList.size();
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String searchTerm = constraint.toString().toLowerCase();
                Log.w(TAG, "search " + searchTerm);
                if (searchTerm.isEmpty()) {
                    filteredLocationList = locationList;
                } else {
                    List<Location> filteredList = new ArrayList<>();
                    for (Location location : locationList) {
                        if (location.locName.toLowerCase().contains(searchTerm)) {
                            Log.i("location search", location.locName);
                            filteredList.add(location);
                        }
                    }
                    filteredLocationList = filteredList;
                }

                FilterResults searchResults = new FilterResults();
                searchResults.values = filteredLocationList;
                return searchResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                filteredLocationList = (ArrayList<Location>) results.values;
                notifyDataSetChanged();
            }
        };
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name, district;

        MyViewHolder(View view) {
            super(view);
            name = view.findViewById(R.id.name);
            district = view.findViewById(R.id.district);
        }
    }
}

The Log statements show the Locations are being found but the List is not updating accordingly. What could be the cause of this.


Solution

  • After referring to this tutorial, I made some changes to the getFilter() and publishResults() methods which seemed to have done the trick. The search results' values and count were assigned after searching. In the publishResults the adapter was used
    getFilter():

    searchResults.values = filteredLocationList;
    searchResults.count = filteredLocationList.size();
    

    publishResults():

    adapter.filteredLocationList = (ArrayList<Location>) results.values;
    adapter.notifyDataSetChanged();