Search through RecyclerView with Searchview

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

 public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> { private LayoutInflater inflater; private List<BaseOfCards> items; //private int itemLayout; //String cardvalue; private Activity mActivity; public RecyclerViewAdapter(Activity mActivity, Context context, List<BaseOfCards> items) { this.mActivity = mActivity; inflater = LayoutInflater.from(context); this.items = items; //this.itemLayout = itemLayout; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.custom_row, parent, false); MyViewHolder holder = new MyViewHolder(view, mActivity); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { BaseOfCards item = items.get(position); holder.title.setTag(item); holder.title.setText(item.getCardName()); } @Override public int getItemCount() { return items.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { private Activity mActivity; TextView title; ImageView titileImageView; public MyViewHolder(View itemView, Activity mActivity) { super(itemView); titileImageView = (ImageView) itemView.findViewById(R.id.image_country); title = (TextView) itemView.findViewById(R.id.listText); this.mActivity = mActivity; } } } 

I add SearchView to my menu and initialize it in MainActivity :

  MenuItem menuItem = menu.findItem(R.id.action_search1); searchView = (SearchView) MenuItemCompat.getActionView(menuItem); SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView.setIconifiedByDefault(true); 

What do I need to do next? Do my RecyclerViewAdapter implement Filterable or what? Or just enter the filter class in * RecyclerViewAdapter ** and just call it from my MainActivity ?

+7
android searchview android-recyclerview recycler-adapter
source share
4 answers

I solved my problem

  • Make my class RecyclerViewAdapter implements Filterable

  • Add line private List<BaseOfCards> orig;

  • Add getFilter method to 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(); } }; 
  • Make MainActivity implements SearchView.OnQueryTextListener and change the onQueryTextChange method:

     @Override public boolean onQueryTextChange(String newText) { if ( TextUtils.isEmpty ( newText ) ) { adapter.getFilter().filter(""); } else { adapter.getFilter().filter(newText.toString()); } return true; } 
+19
source share

Using autocompletetextview or edittext, I processed this, following where

  public List<SalesProductsItems> mItems 

is the original instance of listitem and.

  public static List<SalesProductsItems> filteredIt 

is an instance used when displaying items. Since the first time the filter results are not null, the mItems instance will be equal to the filteredIt instance (thus losing the original list), and then, according to the rule of the publishResults method publishResults before mItems loses its original values, I equate it to the passed originallist instance. Hope this 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
source share

I want to add an answer to ololoking . In MainActivity we also need to add the following code for it to 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); } 

Thank you, thanks for your reply. It helps me.

0
source share

From the moment another positive answer was executed, I have now implemented a fast asynchronous filter using AsyncTask in FlexibleAdapter , the performance is very good with large lists, with animation too! The adapter is configured to enable / disable properties as a result of filtering to increase speed when necessary. Another big advantage is that the interface is still responsive to the user.

A test performed on my Samsung S3 running Android 6: with a starting list of 10,450 elements, it takes ~ 1 s from the moment the background process starts to filter the character and select 3,890 elements.

I also made a Wiki link with all the details of using a filter with an adapter.

0
source share

All Articles