使用SearchviewsearchRecyclerView

我想通过RecyclerView进行search,我有List<BaseOfCards> (BaseOfCards是我的getter&setter类)我的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; } } } 

我将SearchView添加到我的菜单并在MainActivity中初始化它:

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

接下来我需要做什么? 让我的RecyclerViewAdapter implement Filterable或什么? 或者只是在* RecyclerViewAdapter **中创build类filter ,并从我的MainActivity中调用它?

Solutions Collecting From Web of "使用SearchviewsearchRecyclerView"

我解决了我的问题

  1. 让我的类RecyclerViewAdapter implements Filterable

  2. 添加行private List<BaseOfCards> orig;

  3. RecyclerViewAdapter中添加getFilter方法

     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. 使MainActivity implements SearchView.OnQueryTextListener并更改onQueryTextChange方法:

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

使用自动完成文本视图或edittext我处理这一个如下

  public List<SalesProductsItems> mItems 

是最初的listitem实例和。

  public static List<SalesProductsItems> filteredIt 

是用于显示items的实例。由于第一次过滤结果不为null,所以mItems实例将等于filteredIt实例(因此丢失初始列表),然后在mItems失去原始值之前的publishResults方法中,I'等同于通过实例的originallist 。 希望它可以帮助别人

 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(); } } } 

我想添加ololoking的答案。 在MainActivity我们还应该添加下一个代码,以便它能够工作:

  @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); } 

感谢ololoking你的答案。 它帮助了我。

从其他正面答案完成后,我现在在我的FlexibleAdapter库中使用AsyncTask实现了一个快速asynchronousfilter ,对于大列表,性能也非常好,同时还有animation! 该适配器可configuration为启用/禁用过滤结果中的属性,以在必要时提高速度。 另一个很大的优势是接口仍然对用户做出响应。

在我运行Android 6的三星S3中完成的testing:从10.450项目的起始列表,从后台进程开始的那一刻起,需要大约1秒来过滤字符并select3.890项目。

我也做了一个Wiki页面,其中包含所有的细节,以便使用适配器进行过滤。