如何通过其他东西过滤ListView然后CharSequence?

时间:2015-07-21 06:55:51

标签: android

我正在撰写自定义BaseAdapter(由Set支持),我需要通过CharSequence以外的其他内容过滤数据(价格范围,颜色等) 。

我查看了Filterable界面和Filter类,但Filter中的所有方法都使用CharSequence s。

那么,该怎么做?我应该将过滤器参数编码为CharSequence(可能是JSON吗?),还是有更好的方法?

此外,convertResultToString方法的优点是什么?因为我不希望结果为String,而Object来自Set,因为我显示的信息更多,只有String。< / p>

3 个答案:

答案 0 :(得分:1)

您可以根据需要进行过滤,但需要编写一些代码。

  1. 在适配器中,为您的集创建另一个字段。它将是您实际显示的集合。这意味着在您的所有getCountgetViewgetItemIdgetItem方法中,您应该使用第二个集合(实际上是在适配器中的evrywhere)。默认情况下,它应与您的主要数据集相同。您的主要数据集将是mSet和展示mDisplaySet

  2. 创建自定义过滤器方法。此方法将过滤放入第二组(实际显示的那个)第一组中与给定条件匹配的元素:

    public void filter(Object condition) {
        mDisplaySet = new Set<>();
        for (Object object : mSet) {
            if (object.match(condition) {
                mDisplaySet.add(object);
            }
        }
        notifyDataSetChanged();
    }
    

答案 1 :(得分:1)

如果您实现了FilterableFilter,并且由于您的适配器由一组元素支持,您可以忽略CharSequences方法中的public FilterResults performFiltering(CharSequence prefix)。在适配器内部,复制一组元素,这些元素将用于填充ListView或您正在使用的任何元素。

之后,在performFiltering(...)方法中,只需按您选择的条件删除元素:

private class ClientsFilter extends Filter {

        @Override
        public FilterResults performFiltering(CharSequence prefix) {

            // Thats the result of our filtering process
            FilterResults results = new FilterResults();

            synchronized (mLock) {

                // It's a good idea to work with a copy of the original set of elements, so we can reuse it every time we want to filter
                ArrayList<Client> filteredClients = new ArrayList<>(originalClients); 

                    for (int i = 0; i < filteredClient.size(); i++) {
                        if (// !fit my criteria) {
                            // We remove the clients that doesn`t fit the criteria, so only the good ones stay here
                            filteredClients.remove(i);
                            i--;
                        }
                    }

                results.values = filteredClients;
                results.count = filteredClients.size();
            }

            return results;

        }

        @Override
        protected void publishResults(CharSequence prefix, FilterResults results) {
            // And we use the filtered clients in our ListView, GridView or whatever
            listViewClients= (ArrayList<Client>) results.values;
            adapter.notifyDataSetChanged();
        }
    }

一些提示:

  • 不要忘记使用synchronized内容,否则您会遇到一些有趣的错误(NPE没有任何明显原因造成的竞争条件)
  • 使用Filterable过滤进程在后台进行,因此用户界面保持响应
  • 如果要过滤结果,请调用adapter.getFilter().filter()方法,例如在EditText
  • 中撰写时

答案 2 :(得分:1)

我仔细查看了你的问题,我将逐一回答。
1。那么,该怎么做?我应该将过滤器参数编码为CharSequence(可能是JSON吗?),还是有更好的方法?
我认为你不应该对它进行编码,只需按以下方式进行编码:

public class YourFilterObject { 
    String test1;
    int test2;
}
private YourFilterObject yourFilterObject;
public TestAdapter setFilterObject(YourFilterObject object) {
    this.yourFilterObject = object;
    return this;
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            // use yourFilterObject here to filter your adapter
            return null;
        }
        @Override
        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        }
    };
}

每当您想使用自定义参数(不仅仅是字符串)过滤适配器时,您都可以拨打电话YourAdapter.setFilterObject(object).getFilter().filter(null);
2。什么是convertResultToString方法适用于 实际上这个方法我只用于AutocompleteTextView。当您在AutocompleteTextView中输入内容(例如:name ...)时,它会显示filterResults中要选择的对象列表。当您选择结果对象时,将调用convertResultToString函数以在Text中设置(显示)AutocompleteTextView。如果您不重写此方法,则在选择对象后,AutocompleteTextView将不会显示任何内容。
希望这有帮助。