首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ListView滤波视觉问题

ListView滤波视觉问题
EN

Stack Overflow用户
提问于 2014-04-02 15:40:56
回答 2查看 72关注 0票数 0

当在ArrayAdapter<T>子类上使用自定义筛选器时,在运行时显示所有元素的容器ListView 在显示实际筛选列表之前,总是会得到它。

当用户使用SearchView/TextView进行过滤,并且过滤器事件需要被称为onQueryTextChange时,这对用户尤其有害,这使得过滤器在每个按键上看起来都是重置的。

我的实现通常是这样的:

代码语言:javascript
复制
public class FilterAdapter extends ArrayAdapter<ListElement> {
    private Context mContext;
    public List<ListElement> listElements;

..。

代码语言:javascript
复制
@Override
public Filter getFilter(){
    return new Filter(){
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            Locale currentLocale = mContext.getResources().getConfiguration().locale;
            constraint = constraint.toString().toLowerCase(currentLocale);

            FilterResults results = new FilterResults();

            if (constraint == null || constraint.length() == 0) {
                //get a COPY of the original elements array not to change it by reference
                results.values = new ArrayList<ListElement>(FilterAdapter.this.listElements);
                results.count = listElements.size();
            }
            else{
                List<ListElement> found = new ArrayList<ListElement>();
                for(ListElement item : FilterAdapter.this.listElements){
                    if(item.filterString().toLowerCase(currentLocale).contains(constraint)){
                        found.add(item);    //no need to create a copy of single element
                    }
                }
                results.values = found;
                results.count = found.size();
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            clear();
            for (ListElement item : (List<ListElement>) results.values) {
                add(item);
            }
            notifyDataSetChanged();
        }
    };
}

据我理解,Filter.performFiltering子类AsyncTask (或者至少在它自己的线程中运行,从未真正到AOSP进行检查),Filter.publishResults只是适配器UI线程的一个处理程序。

我看到的过滤器的每一个实现都倾向于在ArrayList.clear()ArrayList.notifyDataSetChanged开始和结束时调用publishResults,而且我从来没有在没有clear+notify的情况下使用过滤器.尽管我很漂亮

删除第二次重置的那一小部分,然后一次从一个过滤列表转到另一个筛选列表,有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2014-04-02 15:58:08

尝试将此android:scrollingCache="false"添加到布局文件中的<ListView>元素中。

票数 0
EN

Stack Overflow用户

发布于 2014-04-02 16:18:22

实际上,我在询问之后偶然发现了一个解决方案500万,同时解决了一个糟糕的getCount()问题:问题是最初怀疑的同步问题。我是这么叫过滤器的..。

代码语言:javascript
复制
auxAdapter.getFilter().filter(currentUserTextFilter);

//and sequentially I replaced the old adapter on the list
contactsAdapter = auxAdapter;
listViewContacts.setAdapter(contactsAdapter);

//...bunch of other operations in between, and then...
Log.i(activityName, "Item count: " + listViewContacts.getAdapter().getCount());

...and .filter(String constraint)没有阻塞,实际上比设置新适配器花费的时间更长,因此它显示了完整的列表一段时间,还为我提供了一个意外的(但正确的)项计数(当我实际调试该计数时)。

工作代码使用filter(CharSequence constraint, Filter.FilterListener listener),而不是只使用约束版本:

代码语言:javascript
复制
auxAdapter.getFilter().filter(currentUserTextFilter, new Filter.FilterListener() {
            public void onFilterComplete(int count) {
                contactsAdapter = auxAdapter;

                contactsAdapter.setNotifyOnChange(true);
                listViewContacts.setAdapter(contactsAdapter);
                updateTitle();
            }
        });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22816499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档