Search through RecyclerView using Searchview

前端 未结 5 390
谎友^
谎友^ 2020-12-16 23:31

I want to search through RecyclerView, I have List (BaseOfCards is my getter&setter class) My RecyclerViewAdapter<

相关标签:
5条回答
  • 2020-12-16 23:49

    I solved my problem

    1. Make my class RecyclerViewAdapter implements Filterable

    2. Add line private List<BaseOfCards> orig;

    3. Add method getFilter in RecyclerViewAdapter

      public Filter getFilter() {
      return new Filter() {
          @Override
          protected FilterResults performFiltering(CharSequence constraint) {
              final FilterResults oReturn = new FilterResults();
              final List<BaseOfCards> results = new ArrayList<BaseOfCards>();
              if (orig == null)
                  orig  = items;
                  if (constraint != null){
                      if(orig !=null & orig.size()>0 ){
                          for ( final BaseOfCards g :orig) {
                              if (g.getCardName().toLowerCase().contains(constraint.toString()))results.add(g);
                          }
                      }
                      oReturn.values = results;
                  }
                  return oReturn;
              }
      
      @Override
          protected void publishResults(CharSequence constraint, FilterResults results) {
              items = (ArrayList<BaseOfCards>)results.values;
              notifyDataSetChanged();
      
          }
      }; 
      
    4. Make MainActivity implements SearchView.OnQueryTextListener and change method onQueryTextChange :

      @Override
      public boolean onQueryTextChange(String newText) {
          if ( TextUtils.isEmpty ( newText ) ) {
              adapter.getFilter().filter("");
          } else {
              adapter.getFilter().filter(newText.toString());
          }
          return true;
      }
      
    0 讨论(0)
  • 2020-12-16 23:56

    From the time the other positive answer was done, I've now implemented a fast async filter using AsyncTask in my FlexibleAdapter library, performance are very good with big lists, having animations too! The Adapter is configurable to enable/disable properties in filtering result to increase speed when necessary. Another big advantage is also that interface is still responding to the user.

    Test done in my Samsung S3 running Android 6: with a starting list of 10.450 items, from the moment the background process starts it takes ~1s to filter a character and select 3.890 items.

    I've done also a Wiki page with all the details to use filter with the Adapter.

    0 讨论(0)
  • 2020-12-17 00:00

    I want to add to ololoking answer. In MainActivity we should also add next code so it would work:

       @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_layout, menu);
    
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView.setIconifiedByDefault(true);
        searchView.setOnQueryTextListener(this);
        return super.onCreateOptionsMenu(menu);
    
    }
    

    Thanks ololoking for your answer. It helped me.

    0 讨论(0)
  • 2020-12-17 00:09

    In your adapter class extend filterable. Then override the public Filter getFilter().

       @Override
        public Filter getFilter() {
            Filter filter = new Filter() {
                @Override
                protected FilterResults performFiltering(CharSequence charSequence) {
                    FilterResults filterResults = new FilterResults();
    
                    if(charSequence == null | charSequence.length() == 0){
                        filterResults.count = getUserModelListFiltered.size();
                        filterResults.values = getUserModelListFiltered;
    
                    }else{
                        String searchChr = charSequence.toString().toLowerCase();
    
                        List<UserModel> resultData = new ArrayList<>();
    
                        for(UserModel userModel: getUserModelListFiltered){
                            if(userModel.getUserName().toLowerCase().contains(searchChr)){
                                resultData.add(userModel);
                            }
                        }
                        filterResults.count = resultData.size();
                        filterResults.values = resultData;
    
                    }
    
                    return filterResults;
                }
    
                @Override
                protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
    
                    userModelList = (List<UserModel>) filterResults.values;
                    notifyDataSetChanged();
    
                }
            };
            return filter;
          }
    

    in your main activity add search view and listener to onQueryTextChange.

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
    
        MenuItem menuItem = menu.findItem(R.id.search_view);
    
        SearchView searchView = (SearchView) menuItem.getActionView();
    
        searchView.setMaxWidth(Integer.MAX_VALUE);
    
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }
    
            @Override
            public boolean onQueryTextChange(String newText) {
    
                usersAdapter.getFilter().filter(newText);
                return true;
            }
        });
    
    
    
        return  true;
    }
    

    Full tutorial and source code. Recyclerview with SearchView

    0 讨论(0)
  • 2020-12-17 00:15

    Using an autocompletetextview or an edittext i handled this one as following where

     public List<SalesProductsItems> mItems          
    

    is the initial listitem instance and .

      public static List<SalesProductsItems> filteredIt 
    

    is the instance used in displaying items.Since the 1st time the filter results is not null the mItems instance will be equal to the filteredIt instance (thus loosing the initial list) then on the publishResults method right before mItems looses the original values, I'm equating it to the passed instance originallist . Hope it helps someone

    private static class ProductsFilter extends Filter {
    
        private final SalesProductsAdapter adapter;
    
        private final List<SalesProductsItems> originalList;
    
        private final List<SalesProductsItems> filteredList;
    
        private ProductsFilter(SalesProductsAdapter adapter, List<SalesProductsItems> originalList) {
            super();
            this.adapter = adapter;
            this.originalList = new LinkedList<>(originalList);
            this.filteredList = new ArrayList<>();
        }
    
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            filteredList.clear();
            final FilterResults results = new FilterResults();
    
            if (constraint == null || constraint.length() == 0)
                filteredList.addAll(originalList);
            else {
                final String filterPattern = constraint.toString().toLowerCase().trim();
    
                for (final SalesProductsItems it : originalList) {
    
                    if (it.getProduct().toLowerCase().contains(filterPattern)) {
                        filteredList.add(it);
                    }
                }
            }
    
            results.values = filteredList;
            results.count = filteredList.size();
            return results;
        }
    
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            adapter.mItems = originalList;
            if(results.count > 0) {
                filteredIt.clear();
                filteredIt.addAll((ArrayList<SalesProductsItems>) results.values);
                adapter.notifyDataSetChanged();
            } else {
                filteredIt.clear();
                filteredIt.addAll(adapter.mItems);
                adapter.notifyDataSetChanged();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题