【问题标题】:Toolbar with SearchView temporary filtering RecyclerView带有 SearchView 临时过滤 RecyclerView 的工具栏
【发布时间】:2015-03-03 10:42:42
【问题描述】:

我需要在我的 android 应用程序中实现搜索功能,该应用程序使用工具栏、SlidingTabLayout 和包含片段的 ViewPager。每个片段内部都有一个包含项目列表的 RecyclerView。

RecyclerView 数据是在单独的类 (DataAccess.java) 中静态定义的,这些列表会被更新,并且 RecyclerView 只需通过调用即可刷新(不传递新数据)

mRecyclerView.getAdapter().notifyDataSetChanged();

有没有什么简单的方法可以在不更改数据的情况下临时过滤 RecyclerView,并且在用户按下工具栏中的返回按钮以删除过滤器并显示初始列表后。

在工具栏菜单中按下搜索图标之前:

因此,当用户输入“Josip...”时,过滤器将处于活动状态

在 SearchView 中按下 X 按钮后,用户将获得与以前相同的数据,无需过滤。

@Override 
public boolean onQueryTextChange(String newText) {
    // filter data (temporary remove all items from DataAccess.list that don't .startsWith(newText)
}

@Override 
public boolean onQueryTextSubmit(String query)
    // Doesn't help if I revert deleted items here
}

【问题讨论】:

    标签: android-fragments searchview android-recyclerview android-toolbar


    【解决方案1】:
    @Override 
    public boolean onQueryTextSubmit(String query){
        ((ItemAdapter) myRecList.getAdapter()).setFilter(query)
    }
    

    public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
    
        private List<String> visibleObjects;
        private List<String> allObjects;
    
        .....
    
        public void flushFilter(){
            visibleObjects=new ArrayList<>();
            visibleObjects.addAll(allObjects);
            notifyDataSetChanged();
        }
    
        public void setFilter(String queryText) {
    
            visibleObjects = new ArrayList<>();
            constraint = constraint.toString().toLowerCase();
            for (String item: allObjects) {            
                    if (item.toLowerCase().contains(queryText))                     
                        visibleObjects.add(item);            
            }
           notifyDataSetChanged();
        }
    }
    

    【讨论】:

    • IN @Override public boolean onQueryTextChange(String newText) { if (text.isEmpty()) ((ItemAdapter) myRecList.getAdapter).flushFilter(); } OR IN OnActionExpandListener.onMenuItemActionCollapse(MenuItem item)
    • searchView.setOnCloseListener() 是问题,无论如何,谢谢你的评论让我走上了正确的道路!
    • @fpopic 你能发布你的解决方案吗?
    • 我没有时间完成它,因为答案来晚了,但你试过这个@merovingen 的答案吗,看起来不错?
    【解决方案2】:

    我想添加评论,但由于声誉较低......我正在回复帖子。 如果 (item.toLowerCase().contains(queryText)) 此方法工作正常,但如果在第一次迭代中未找到匹配项该怎么办。然后它将进入 else 部分而不循环整个 allObjects 列表...

    for (RouteByATMList.Route_ATM item: Main_ATMItemList)
            {
    
                if (item.ATMNumber.contains(queryText)) {
                    visibleObjects.add(item);
                }else {
                    Toast.makeText(mContext,"No search result found!",Toast.LENGTH_SHORT).show();
                    break;
                }
            }
    

    我从上级那里得到了答案,希望对你有帮助。

    public void setFilter(String queryText) {
            visibleObjects = new ArrayList<>();
            for (RouteByATMList.Route_ATM item: Main_ATMItemList)
            {
                if (item.ATMNumber.contains(queryText))
                {
                    visibleObjects.add(item);
                }
            }
    
            if(visibleObjects.size()==0){
                Toast.makeText(mContext,"No search result found!",Toast.LENGTH_SHORT).show();
            }
    
            notifyDataSetChanged();
            Log.e("dataset changed","dataset changed");
        }
    

    【讨论】:

      【解决方案3】:

      我不反对给出和接受的答案。可能存在性能缺陷。应该使用Filterabe 接口。实现此功能将表现得像 ol'good ListView 异步进行过滤。那么你只需要编写自己的Filter 并在重写的getFilter() 方法中实例化它;

      在我的例子中,我使用Filter 对包含许多(是的,许多)项目的适配器进行排序。在 UI 线程上对其进行排序很垃圾。

      所以我有了这个抽象类

      public abstract class BaseFilterableRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements Filterable {
      
          private Context mContext;
          public BaseFilterableRecyclerViewAdapter(Context context) {
              this.mContext = context;
          }
          public abstract void sort(SortingFilter.Sort sortingStrategy);
      
          //...Other methods
      
      }
      

      以及继承的类:

      public class ItemAdapter extends BaseFilterableRecyclerViewAdapter<RecyclerView.ViewHolder>{
      
      
        //... RecyclerView methods
      
      
        @Override
          public Filter getFilter() {
              return new SortingFilter(mData) {
                  @Override
                  protected void publishResults(CharSequence constraint, FilterResults results) {
                      if (results.values != null) {
                          int last = mData.size();
                          mData = (List<Product>) results.values;
                          notifyDataSetChanged();
                      }
                  }
              };
          }
      
      
      
          @Override
          public void sort(SortingFilter.Sort sortingStrategy) {
              getFilter().filter(sortingStrategy.toString());
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-24
        • 2015-11-09
        • 1970-01-01
        • 2015-10-29
        • 2016-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多