2015-02-24 114 views
7

我想通过RecyclerView搜索,我有List<BaseOfCards>(BaseOfCards是我的getter &二传手类) 我RecyclerViewAdapter搜索通过RecyclerView使用搜索查看

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; 

    } 
} 

} 

我添加搜索查看我的菜单,并在初始化MainActivity

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

我需要什么,下一步该怎么做?让我的RecyclerViewAdapterimplement Filterable还是什么?或者只是在* RecyclerViewAdapter **中创建类filter,并从我的MainActivity中调用它?

回答

19

我解决我的问题

  1. 让我的课RecyclerViewAdapterimplements Filterable

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

  3. Add方法getFilterRecyclerViewAdapter

    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. MainActivityimplements SearchView.OnQueryTextListener和改变方法onQueryTextChange

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

很酷,我会在我的https://github.com/davideas/FlexibleAdapter ;-)中加入这个功能('getFilter');-) – Davidea 2015-07-20 21:03:04

+0

@Davidea哦,非常棒,非常感谢! – Ololoking 2015-07-20 21:59:33

+0

我添加了这个功能,但它比预想的更复杂。事实上,我不相信在适配器中有这样的过滤器,因为适配器中的对象已经是**原始内容中来自诸如DB/XML/JSON之类的源的副本,作为域对象 - 问题不在过滤器上,而是在**过滤的**列表上执行的add/del/mod:所有更改都应该反映在“原始”适配器列表中** AND **在原始源代码中... At此点更方便直接从源和更新适配器与该列表中筛选复制列表。 – Davidea 2015-07-21 11:56:58

0

使用一个autocompletetextview或一个EditText我处理这一个如下其中

public List<SalesProductsItems> mItems   

是初始列表项实例和。

public static List<SalesProductsItems> filteredIt 

在显示items.Since所述第一时间的过滤器的结果是不是空的mItems实例将等于filteredIt实例使用的实例(而丧失的初始列表)然后在publishResults方法mItems前右失去原始值,我将它与传递的实例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(); 
     } 
    } 
} 
0

我想补充到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你的答案。它帮助了我。

0

从另一方面肯定的回答做的时候,我现在已经在我FlexibleAdapter库中实现一个快速异步滤波器使用AsyncTask,表现都非常好,大名单,有动画呢! 该适配器可配置为启用/禁用过滤结果中的属性,以在必要时提高速度。另一大优势还在于界面仍然对用户做出响应。

在运行Android 6的我的三星S3中完成的测试:从10.450项目的起始列表开始,从后台进程开始的那一刻起,需要花费大约1秒来筛选一个字符并选择3.890项目。

我也做了一个Wiki page与所有的细节使用过滤器与适配器。

+0

我是同样的问题,你解决了这个问题。请帮助我@Davidea – 2017-12-29 07:44:18

+0

@SagarHudge,从我以前的评论时间到接受的答案,我的过滤器发生了变化,目前的过滤方式在wiki页面中有描述。空间做得更好,并且与Filter类相似,但现在这是FlexibleAdapter的方式。 – Davidea 2017-12-29 16:59:38