How to search a list of Objects that are displayed in a RecyclerView?

非 Y 不嫁゛ 提交于 2019-12-08 10:54:20

问题


I am currently trying to implement a SearchView, but the displayed search results change only for the first Search, everything else I enter into SearchView is ignored.

Here is my Code for Searching in my MainActivity.java:

testList = Arrays.asList(new TestItem("aw"), new TestItem("aa"), new TestItem("w"));

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.test_menu, menu);

    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setOnQueryTextListener(this);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onQueryTextChange(String newText) {
    List<TestItem> result = new ArrayList<>();
    for(TestItem t: testList) {
        if(t.getName().contains(newText) {
            result.add(t);
        }
    }
    adapter.changeList(result);
    return true;
}

adapter.changeList:

public void changeList(List<TestItem> newList) {
    this.list = new ArrayList<>(newList);
}

onQueryTextChange gets called after each text change, but the search result is shown only once. When entering a and Enter the RecyclerView shows aw and aa (is it normal to have to press Enter for onQueryTextChange to start?), but when I then enter aa the displayed items stay the same.


回答1:


I think your implementation is not correct. You don't need to press the enter for search result. For implementation you can keep a intact copy of your array list.Then make another temporary list form that list when query text is changed. So when you are filtering, you are searching the actual list not the filtered list.

1.pass search keyword to the list adapter

public boolean onQueryTextChange(String newText) {

    adapter.getFilter().filter(newText);
    return true;
}

2. In adapter implement Filterable and override method

@Override
public Filter getFilter() {
    if (frameFilter == null) {
        frameFilter = new FrameFilter();
    }

    return frameFilter;
}

3. Filtering class can be something like this: 'categoryMain' is my intact list and 'categoryTemp' is my temporary list

private class FrameFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        FilterResults filterResults = new FilterResults();
        if (constraint != null && constraint.length() > 0) {
            ArrayList<Category> tempList = new ArrayList<>();

            // search content in friend list
            Log.i("key",constraint.toString());
            for (Category category : categoriesMain) {
                if (category.getCategory_name().toLowerCase().contains(constraint.toString().toLowerCase())) {
                    tempList.add(category);
                }
            }
            filterResults.count = tempList.size();
            filterResults.values = tempList;
        } else {

            filterResults.count = categoriesMain.size();
            filterResults.values = categoriesMain.clone();
        }
        return filterResults;
    }

    /**
     * Notify about filtered list to ui
     *
     * @param constraint text
     * @param results    filtered result
     */
    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {

        categoriesTemp = (ArrayList<Category>) results.values;
        notifyDataSetChanged();
    }
}


来源:https://stackoverflow.com/questions/44977042/how-to-search-a-list-of-objects-that-are-displayed-in-a-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!