Search code examples
androidfilteringsearchviewandroid-recyclerview

Setting previous results back in recycler view when a text is delected from Search view's Filter


I am having trouble with Setting previous results back in recyclerView when a text is deleted from searchView's Filter box. I use the following code in the adapter which filters the data finely. But the thing is it does not set the previous values in the recyclerView when the search text is deleted from the search view.

recyclerView adapter's get filter method

@Override
    public  Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    results = names;
                } else {
                    ArrayList<tab> filteredList = new ArrayList<>();
                    for (tab row : names) {

                        // name match condition. this might differ depending on your requirement
                        // here we are looking for name or phone number match
                        if (row.getName().toLowerCase().contains(charString.toLowerCase()) || row.getmsg().contains(charSequence)) {
                            filteredList.add(row);
                        }
                    }

                    results = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = results;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                names = (ArrayList<tab>) filterResults.values;

                // refresh the list with filtered data
                notifyDataSetChanged();
            }
        };
    }

Main activity code

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.action_search)
                .getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));
        searchView.setMaxWidth(Integer.MAX_VALUE);

        // listening to search query text change
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // filter recycler view when query submitted
                gtxx.getFilter().filter(query);
               // gtxx.notifyDataSetChanged();
                return false;
            }

            @Override
            public boolean onQueryTextChange(String query) {
                // filter recycler view when text is changed
               gtxx.getFilter().filter(query);
               //gtxx.notifyDataSetChanged();
                return false;
            }
        });
        return true;

    }

Setting value in the adapter

 gtxx = new listadapttor(con_list);

            recyclerView.setAdapter(gtxx);

Solution

  • In your adapter create two list, with the same data. Let say second list is temporary list. Set adapter using that list and do filtering on the second list from first list. Refer the code below:

    private List<YourObject> tempList;
    
    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {
    
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
    
                //this is the main list, which contains filtered items
                //and tempList always contains original data.
                //so when empty text is passed to filterable it will reset
                //the list using original data from tempList
                mainList = (List<YourObject>) results.values;
                notifyDataSetChanged();
            }
    
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
    
                FilterResults results = new FilterResults();
    
                if (constraint != null && constraint.toString().length() > 0) {
                    List<YourObject> filteredItems = new ArrayList<YourObject>();
                    for (int i = 0; i < tempList.size(); i++) {
                        YourObject data = tempList.get(i);
                        if ((data.getName() != null && data.getName().toLowerCase().contains(constraint.toString().toLowerCase()))) { //Your filtering code here
                            filteredItems.add(data);
                        }
                    }
    
                    results.count = filteredItems.size();
                    results.values = filteredItems;
    
                }
                else
                {
                    synchronized (this) {
                        results.values = tempList;
                        results.count = tempList.size();
                    }
                }
                return results;
            }
        };
    
        return filter;
    }