2

这是我的过滤器的代码:

private class NameFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        // NOTE: this function is *always* called from a background thread,
        // and
        // not the UI thread.
        constraint = constraint.toString().toLowerCase();
        FilterResults result = new FilterResults();
        if (constraint != null && constraint.toString().length() > 0) {
            ArrayList<Place> filt = new ArrayList<Place>();
            ArrayList<Place> lItems = new ArrayList<Place>();
            synchronized (this) {
                lItems.addAll(objects);
            }
            for (int i = 0, l = lItems.size(); i < l; i++) {
                Place m = lItems.get(i);
                if (m.getName().toLowerCase().contains(constraint))
                    filt.add(m);
            }
            result.count = filt.size();
            result.values = filt;
        } 
        else {
            synchronized (this) {
                result.values = objects;
                result.count = objects.size();
            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint,
            FilterResults results) {
        // NOTE: this function is *always* called from the UI thread.
        filtered = (ArrayList<Place>) results.values;
        notifyDataSetChanged();
        clear();
        for (int i = 0, l = filtered.size(); i < l; i++)
            add(filtered.get(i));
        notifyDataSetInvalidated();
    }

}

这是我的活动代码:

lvPlace = (ListView) findViewById(R.id.listView1);

    final ArrayList<Place> searchResults = GetSearchResults();

    filterEditText = (EditText) findViewById(R.id.filter_text);
    filterEditText.addTextChangedListener(filterTextWatcher);

    adapter = new PlaceAdapter(this, 0, searchResults);

    lvPlace.setAdapter(adapter);
    lvPlace.requestFocus();
    lvPlace.setTextFilterEnabled(true);

private TextWatcher filterTextWatcher = new TextWatcher() {

    public void afterTextChanged(Editable s) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (adapter != null) {
            adapter.getFilter().filter(s.toString().toLowerCase());
            filterEditText.getText().toString();
        } else {
            Log.d("filter", "no filter availible");
        }
    }

};

@Override
protected void onDestroy() {
    super.onDestroy();
    filterEditText.removeTextChangedListener(filterTextWatcher);
}

我已经为此苦苦挣扎了一段时间,因为当我在搜索框中输入内容时它工作正常,但是一旦我从搜索字段中删除了文本,列表就不会返回到初始状态。请帮我解决这个问题!

4

2 回答 2

0

publishResults在你的方法中试试这个:

protected void publishResults(CharSequence constraint,FilterResults results)
{   
    filtered.clear();
    filtered = (ArrayList<Place>) results.values;
    if(filtered.size() < 1)
        filtered = objects;

    notifyDataSetChanged();

    for (int i = 0, l = filtered.size(); i < l; i++)
        add(filtered.get(i));
    notifyDataSetInvalidated();
}

使用此代码,您可以取出过滤方法中的 else 子句。

另外,您还可以通过使用这样的循环使您的 for 循环更有效率:

for(Place place : filtered)
    add(place);
于 2012-10-01T18:02:35.723 回答
0

当我在搜索框中输入内容时它工作正常,但是一旦我从搜索字段列表中删除了文本并没有返回到初始状态。

如果没有看到适配器的代码,这很可能会发生,因为您没有保留对适配器使用的初始值的引用。例如,如果您ArrayList在适配器中设置了一个带有数据的数据并开始在过滤中输入字符,EditText这将起作用,因为通过过滤您只使用前一组值的子集(这将始终可用)。当您从 中删除一个字符时,EditText您需要对前一组值进行过滤,但随着该组被替换,这些值不再存在并且过滤中断。

解决方案是复制初始值以始终拥有完整ArrayList的值来进行过滤。适配器将使用一个副本ArrayList(这将被过滤结果ArrayList替换publishResults),另一个将用于在方法中由过滤器进行过滤(这ArrayList将保持不变!)performFiltering.

于 2012-10-01T18:08:38.033 回答