【问题标题】:How to set filter for recycler view if search query resulting no match in search view如果搜索查询导致搜索视图中不匹配,如何为回收站视图设置过滤器
【发布时间】:2015-02-05 05:40:53
【问题描述】:

如果我们在搜索视图中输入的项目匹配,但如果我们输入一些不匹配的查询...应用程序在 android 中崩溃,则此代码可以正常工作。

这里的 Main_ATMItemList 是返回整个结果列表的列表。 请帮我添加我需要添加的内容,以便即使查询不匹配代码也能正常工作。

我在适配器类中创建了这个方法

public void setFilter(String queryText) {
        visibleObjects = new ArrayList<>();

            for (RouteByATMList.Route_ATM item : Main_ATMItemList) {
                if (item.ATMNumber.startsWith(queryText))
                {
                    visibleObjects.add(item);

                }
            }
        }

        notifyDataSetChanged();
        Log.e("dataset changed","dataset changed");
    }

【问题讨论】:

  • 如果查询在 for 循环内不匹配,您可以使用 continue
  • 你是说我必须创建 else 然后添加 continue ?
  • 是的,我就是这个意思
  • 我已经完全做到了,但是当我将 toast 放入 else 时,它​​会再次进入 for 循环中的每个条目,并且 toast 继续显示
  • 我需要在进入 for 循环之前进行测试...你能提出一些建议吗

标签: android searchview android-recyclerview


【解决方案1】:

你需要抽象RecyclerView.Adapter并使其继承Filterable。然后将此抽象子类化为要创建的适配器。

重写getFilter() 方法以实例化Filter。在FilterperformFiltering(String constraint) 方法中参考示例如何过滤适配器并移动您现在拥有的逻辑

你应该在后台线程中进行过滤,因此FilterableFilterable 在后台线程上进行过滤,并将结果传递到 UI 线程或调用过滤的线程上。

这样,您可以在一定程度上实现与旧好的ListView 的兼容性。

cmets 中有人问例如:

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

}

在扩展类中:

public class ProductAdapter extends BaseFilterableRecyclerViewAdapter<RecyclerView.ViewHolder>{

//------- Other 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<? extends Product>) results.values;
                    notifyItemRangeChanged(mHeaderView == null ? 0 : 1, last);
                }
            }
        };
    }


}

【讨论】:

  • 一个帮助:如果我执行上述操作,它会在我的 RV 中搜索,但如果我清除搜索或按搜索 x 标记,列表会变为空,为什么?!非常感谢任何帮助或指导,如果一切顺利,我会粘贴答案
  • 举个例子就好了
  • @Nactus 好了。
  • @AditLal 您应该以某种方式为空查询数据保留原始数据。
  • 当从搜索视图中单击关闭 x 符号时如何显示所有项目的所有项目初始视图
【解决方案2】:

一直使用这个对我有用

private List<ExampleModel> filter(List<ExampleModel> models, String query) {
    query = query.toLowerCase();

    final List<ExampleModel> filteredModelList = new ArrayList<>();
    for (ExampleModel model : models) {
        final String text = model.getText().toLowerCase();
        if (text.contains(query)) {
            filteredModelList.add(model);
        }
    }
    return filteredModelList;
}

然后 onQueryTextChange(String query) 调用过滤器

final List<ExampleModel> filteredModelList = filter(mModels, query);
        mAdapter.animateTo(filteredModelList);
        mRecyclerView.scrollToPosition(0);

下面是Adapter中的animateTo方法

 public void animateTo(List<ExampleModel> models) {
        applyAndAnimateRemovals(models);
        applyAndAnimateAdditions(models);
        applyAndAnimateMovedItems(models);
    }

private void applyAndAnimateRemovals(List<ExampleModel> newModels) {
    for (int i = mModels.size() - 1; i >= 0; i--) {
        final ExampleModel model = mModels.get(i);
        if (!newModels.contains(model)) {
            removeItem(i);
        }
    }
}

private void applyAndAnimateAdditions(List<ExampleModel> newModels) {
    for (int i = 0, count = newModels.size(); i < count; i++) {
        final ExampleModel model = newModels.get(i);
        if (!mModels.contains(model)) {
            addItem(i, model);
        }
    }
}

private void applyAndAnimateMovedItems(List<ExampleModel> newModels) {
    for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
        final ExampleModel model = newModels.get(toPosition);
        final int fromPosition = mModels.indexOf(model);
        if (fromPosition >= 0 && fromPosition != toPosition) {
            moveItem(fromPosition, toPosition);
        }
    }
}

public ExampleModel removeItem(int position) {
    final ExampleModel model = mModels.remove(position);
    notifyItemRemoved(position);
    return model;
}

public void addItem(int position, ExampleModel model) {
    mModels.add(position, model);
    notifyItemInserted(position);
}

public void moveItem(int fromPosition, int toPosition) {
    final ExampleModel model = mModels.remove(fromPosition);
    mModels.add(toPosition, model);
    notifyItemMoved(fromPosition, toPosition);
}

}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-28
  • 1970-01-01
相关资源
最近更新 更多