【问题标题】:Search through RecyclerView using Searchview使用 Searchview 搜索 RecyclerView
【发布时间】:2015-04-26 04:19:34
【问题描述】:

我想搜索RecyclerView,我有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** 中创建 filter 类,然后从我的 MainActivity 中调用它?

【问题讨论】:

    标签: android searchview android-recyclerview


    【解决方案1】:

    我的问题解决了

    1. 让我的课RecyclerViewAdapter implements Filterable

    2. 加行private List&lt;BaseOfCards&gt; 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;
      }
      

    【讨论】:

    • 酷,我将使用该方法 (getFilter) 在我的 github.com/davideas/FlexibleAdapter 中添加此功能;-)
    • 我添加了该功能,但它比预想的要复杂。事实上,现在我不相信适配器中有那个过滤器,因为适配器中的对象已经是来自诸如 DB/ 等来源的原始内容的副本内存中的 XML/JSON 作为域对象 - 问题不在于过滤器,而是您在 filtered 列表上执行的 add/del/mod:所有更改也应反映在“原始”适配器列表中 AND 在原始源中...此时更方便的是直接从源中获得过滤后的副本列表并使用该列表更新适配器。
    • 如果你有兴趣在 Dev Branch 下:github.com/davideas/FlexibleAdapter/tree/dev
    • 这里的origitems 是什么?
    • @RevanthRev orig 和 items 是我要过滤的项目列表
    【解决方案2】:

    使用 autocompletetextview 或 edittext 我按如下方式处理了这个

     public List<SalesProductsItems> mItems          
    

    是初始的 listitem 实例,并且 .

      public static List<SalesProductsItems> filteredIt 
    

    是用于显示项目的实例。由于第一次过滤结果不为空,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();
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我想添加到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 的回答。它帮助了我。

      【讨论】:

        【解决方案4】:

        从另一个肯定答案完成后,我现在在我的FlexibleAdapter 库中使用AsyncTask 实现了一个快速异步过滤器,大​​列表的性能非常好,有动画也! 适配器可配置为启用/禁用过滤结果中的属性,以在必要时提高速度。另一个很大的优势是界面仍在响应用户。

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

        我还完成了Wiki page 的所有详细信息,以便将过滤器与适配器一起使用。

        【讨论】:

        • 我有同样的问题,你解决了这个问题吗?请帮助我@Davidea
        • @SagarHudge,从我之前的评论到接受的答案,我的过滤器发生了变化,当前的过滤方式在 wiki 页面中有描述。空间可以做得更好,并且与 Filter 类类似,但现在这就是 FlexibleAdapter 的方式。
        【解决方案5】:

        在您的适配器类中扩展可过滤。 然后覆盖公共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;
              }
        

        在您的主要活动中,将搜索视图和侦听器添加到 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;
        }
        

        完整的教程和源代码。 Recyclerview with SearchView

        【讨论】:

          猜你喜欢
          • 2016-12-23
          • 1970-01-01
          • 1970-01-01
          • 2016-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-07
          相关资源
          最近更新 更多