【问题标题】:Filtering a list during search modifies original data source在搜索期间过滤列表会修改原始数据源
【发布时间】:2016-06-18 16:27:41
【问题描述】:

我刚刚在包含RecyclerView 的视图中添加了SearchView。它工作得很好,但是每次我设置过滤器时,都会根据前一个过滤器进行过滤。此外,当我关闭搜索字段时,完整的数据列表不会重新出现。

这是我在适配器中的内容(我没有列出 onBindViewHolderonCreateViewHolder,但它们在那里):

public class AttractionRowAdapter extends RecyclerView.Adapter<AttractionRowHolder> {
private List<Attraction> attractionsList;
private Context context;

public AttractionRowAdapter(Context context, List<Attraction> attractionsArrayList) {
    this.attractionsList = attractionsArrayList;
    this.context = context;
}

public void setFilter(List<Attraction> attractions) {
    attractionsList.clear();
    attractionsList.addAll(attractions);

    notifyDataSetChanged();
}

public void clearAdaptor() {
    attractionsList.clear();

    notifyDataSetChanged();
}

这就是我在活动中使用RecyclerView 所拥有的:

@Override
public boolean onQueryTextChange(String newText) {
    final List<Attraction> filteredModelList = filter(DataManager.attractionArrayList, newText);
    attractionsAdapter.setFilter(filteredModelList);
    return true;
}

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

    final MenuItem item = menu.findItem(R.id.action_search);
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
    searchView.setOnQueryTextListener(this);

    MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    attractionsAdapter.setFilter(DataManager.attractionArrayList);
                    return true;
                }

                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return true;
                }
            });
    return super.onCreateOptionsMenu(menu);
}

这就是 DataManager 类中的内容:

static ArrayList<Attraction> attractionArrayList = new ArrayList<Attraction>();

我还有一个函数,在从数据库加载所有景点后,我将它们添加到attractionArrayList

问题似乎出在setFilter 方法上,因为我发现它正在修改DataManager.attractionsArrayList

任何人都知道它为什么这样做,以及如何在过滤该列表的副本时保持完整列表完整(就像我尝试过的那样)?

【问题讨论】:

    标签: java android arraylist android-recyclerview searchview


    【解决方案1】:

    你正在这样做:

    public void setFilter(List<Attraction> attractions) {
        attractionsList.clear();
        attractionsList.addAll(attractions);
    }
    

    所以您要向attractionsList 添加attractions 的引用...

    如果您稍后在该方法或类中修改任何这些景点,这些更改也将反映在原始列表中。..

    您“需要”更改算法并可能使用辅助列表,它可以作为帮助者帮助您获得原始列表的不可修改副本

    由于这个原因,Collections 类提供了生成集合副本和不可修改副本的替代方法...

    http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html

    【讨论】:

    • 即使在RecyclerView 活动中创建另一个ArrayList 也不能解决问题。我还是不太明白为什么DataManger 中的列表会被更改。我以为 Java 中的参数总是按值传递的?
    猜你喜欢
    • 2016-12-09
    • 1970-01-01
    • 2019-10-01
    • 2017-05-06
    • 2019-03-27
    • 2014-09-17
    • 1970-01-01
    • 2018-10-17
    • 2020-10-23
    相关资源
    最近更新 更多