列表视图中的过滤器未从完整列表中进行过滤,而是从已过滤的列表中进行了过滤 [英] Filter in listview did not filter from the full list, but from already filtered list

查看:56
本文介绍了列表视图中的过滤器未从完整列表中进行过滤,而是从已过滤的列表中进行了过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带过滤器的列表视图.当我在用作过滤器的edittext中输入一些单词时,例如"david",它可以很好地工作,列表中的项目将被过滤,它将显示所有包含"david"的项目.但是,当我删除某些单词(例如"dav")时,该列表仍会被过滤,但它是从"david"的最后一个过滤条件中过滤出来的.

I have an listview with filter. When I input some words in an edittext that I used as a filter for example "david", it works well, items in the list are filtered and it will show all item that contains "david". But when I delete some words, for example "dav", the list is still filtered, but it filtered from the last filtered by "david".

比方说,我有40个项目,用大卫"过滤后,它变成了24个项目.然后,我再次使用"dav"过滤掉了它,从"24个项目"中过滤掉了,而不是"40个项目"中过滤掉了.

Let's say I had 40 items, filtered by "david", it becomes 24 items. Then I filtered it again with "dav", it filtered from the "24 items" one, not the "40 items" one.

这是我的自定义适配器:

Here is my custom adapter:

public class WRegistrantListAdapter extends ArrayAdapter<Registrant> {

    private Context mContext;
    private int mResource;
    private List<Registrant> mOriginalList;
    private List<Registrant> mFilteredList;

    public WRegistrantListAdapter(Context context, int resource, ArrayList<Registrant> oobjects, int workshopItemId) {
        super(context, resource, oobjects);
        mContext = context;
        mResource = resource;
        mFilteredList = oobjects;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        //contains code for displaying item.
    }

    @NonNull
    @Override
    public Filter getFilter() {
        return new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults result = new FilterResults();
                String constraint = charSequence.toString().toLowerCase();

                if (mOriginalList == null) {
                    mOriginalList = mFilteredList;
                    Toast.makeText(mContext, String.valueOf(mOriginalList.size()), Toast.LENGTH_SHORT).show();
                }

                if (constraint == null || constraint.isEmpty() || constraint.equals("")) {
                    result.values = mOriginalList;
                    result.count = mOriginalList.size();
                } else {
                    List<Registrant> list = new ArrayList<>();
                    int max = mOriginalList.size();
                    for (int cont = 0; cont < max; cont++) {
                        Registrant item = mOriginalList.get(cont);
                        boolean contains =
                            item.getRegistrantName().toLowerCase().contains(constraint) ||
                                    item.getRegistrantNumber().toLowerCase().contains(constraint);
                        if (contains) {
                            list.add(mOriginalList.get(cont));
                        }
                    }
                    result.values = list;
                    result.count = list.size();
                }

                return result;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                clear();
                addAll((ArrayList<Registrant>) results.values);
                notifyDataSetChanged();
            }
        };
    }
}

过滤的哪一部分是错误的?任何帮助将非常感激.希望我的解释不会引起混淆,因为英语不是我的母语.

Which part in the filtering is wrong? Any help would be much appreciated. Hope my explanation is not confusing because English is not my mother language.

推荐答案

您需要两个不同的列表进行过滤,因此请尝试将 mOriginalList = mFilteredList; 更改为 mOriginalList = new ArrayList<>(mFilteredList); 可能会解决此问题.

You need two different lists for filtering, so try change mOriginalList = mFilteredList; to mOriginalList = new ArrayList<>(mFilteredList); may solve the issue.

说明:

mOriginalList = mFilteredList; 是具有两个不同名称的相同列表.在模块化程序中很有用,就像适配器构造函数中的 mFilteredList = oobjects; 一样.

mOriginalList = mFilteredList; is same list with two different names. It is helpful in modular program, just like mFilteredList = oobjects; in your adapter constructor.

mOriginalList = new ArrayList<>(mFilteredList); 是制作mFilteredList的 shallow 副本并将其存储为mOriginalList,因此列表是不同的.

mOriginalList = new ArrayList<>(mFilteredList); is to make a shallow copy of mFilteredList and store it as mOriginalList, so the lists are different.

浅拷贝和深拷贝:

示例:如果您的自定义类注册人包含名为的公共字段(列表,地图或自定义对象等,需要创建新的)样本.在浅表复制下, mOriginalList = new ArrayList<>(mFilteredList); ,mOriginalList.get(i)是mFilteredList.get(i)的副本,它们是两个不同的 Registrant 对象.但是mOriginalList.get(i).sample和mFilteredList.get(i).sample是同一对象.

Example: If your custom class, Registrant, contains a public field (List, Map or custom object etc., that requires new for creation) named sample. Under shallow copy, mOriginalList = new ArrayList<>(mFilteredList);, mOriginalList.get(i) is a copy of mFilteredList.get(i) and they are 2 different Registrant objects. But mOriginalList.get(i).sample and mFilteredList.get(i).sample is the same object.

如果您需要mOriginalList.get(i).sample和mFilteredList.get(i).sample是不同的对象,则称为深度复制.没有现成的方法可以进行深度复制,您必须根据自定义类创建自己的方法.但是到目前为止,我还没有一个需要深入复制的案例.

If you need mOriginalList.get(i).sample and mFilteredList.get(i).sample to be different objects, then it is called deep copy. There is no ready method to make deep copy, you have to make your own method according to your custom class. But up to now, I never have a case that needs deep copy.

希望有帮助!

这篇关于列表视图中的过滤器未从完整列表中进行过滤,而是从已过滤的列表中进行了过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆