前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >listview过滤item(基于ArrayAdapter和BaseAdapter)

listview过滤item(基于ArrayAdapter和BaseAdapter)

作者头像
提莫队长
发布2019-02-21 11:16:00
5960
发布2019-02-21 11:16:00
举报
文章被收录于专栏:刘晓杰刘晓杰

1.基于ArrayAdapter的过滤

ArrayAdapter有个专门的函数用于过滤getFilter,所以只需要运用这个函数就行

代码语言:javascript
复制
        private String[] item = { "1", "2", "3", "4", "5" };

        editText1 = (EditText) findViewById(R.id.editText1);
        listView1 = (ListView) findViewById(R.id.listView1);
        adapter1 = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, item);
        listView1.setAdapter(adapter1);

        editText1.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                adapter1.getFilter().filter(s.toString());
            }

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

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

但是很多时候我们不可能用ArrayAdapter这么简单的适配器,更多的时候是要继承BaseAdapter

2.基于BaseAdapter的过滤

网上其实也有相关的解决方案,但是只告诉你怎么做,却没告诉你原理。今天我来展示一下怎么做。 其实我们也可以仿照ArrayAdapter的getFilter函数自己写一个,那么我们就有必要去看一下源码

代码语言:javascript
复制
    //返回过滤器
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }

    private class ArrayFilter extends Filter {
        //performFiltering函数执行过滤操作,也就是过滤的规则是什么
        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            //FilterResults 是过滤后放置结果的容器,他有两个参数,values 存放结果集,count 存放长度。具体可看源码
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                synchronized (mLock) {
                    mOriginalValues = new ArrayList<T>(mObjects);
                }
            }

            //这一部分就是过滤规则的显示,不难,就是过滤出以prefix开头的元素
            if (prefix == null || prefix.length() == 0) {
                ArrayList<T> list;
                synchronized (mLock) {
                    list = new ArrayList<T>(mOriginalValues);
                }
                results.values = list;
                results.count = list.size();
            } else {
                String prefixString = prefix.toString().toLowerCase();

                ArrayList<T> values;
                synchronized (mLock) {
                    values = new ArrayList<T>(mOriginalValues);
                }

                final int count = values.size();
                final ArrayList<T> newValues = new ArrayList<T>();

                for (int i = 0; i < count; i++) {
                    final T value = values.get(i);
                    final String valueText = value.toString().toLowerCase();

                    // First match against the whole, non-splitted value
                    if (valueText.startsWith(prefixString)) {
                        newValues.add(value);
                    } else {
                        final String[] words = valueText.split(" ");
                        final int wordCount = words.length;

                        // Start at index 0, in case valueText starts with space(s)
                        for (int k = 0; k < wordCount; k++) {
                            if (words[k].startsWith(prefixString)) {
                                newValues.add(value);
                                break;
                            }
                        }
                    }
                }

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

            return results;
        }

        //将过滤后的结果通过mObjects返回并且显示,查看整个源文件你会发现里面有两个List<T>。一个就是保存原本的数据,一个是过滤后的数据,也就是这个mObjects。getItem等函数返回的也是mObjects的长度
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mObjects = (List<T>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }

看懂以上代码。那么arrayadapter的源码也基本看懂,那么接下来我们也来自己做一个

代码语言:javascript
复制
    class MyAdapter extends BaseAdapter {
        private MyFilter mFilter;
        //必须存放两个String[]类型数据,一个保存原始数据,一个用来展示过滤后的数据
        private String[] item;
        private String[] displayItem;

        public MyAdapter(Context context, String[] item) {
            super();
            this.item = item;
            displayItem = item;
        }

        //因为要展示的是过滤后的数据,所以是displayItem的一些属性
        @Override
        public int getCount() {
            return displayItem.length;
        }

        @Override
        public String getItem(int position) {
            return displayItem[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if(convertView == null){
                convertView = new TextView(MainActivity.this);
            }
            ((TextView)convertView).setText(displayItem[position]);
            return convertView;
        }

        //返回过滤器
        public MyFilter getFilter() {
            if (mFilter == null) {
                mFilter = new MyFilter();
            }
            return mFilter;
        }

        class MyFilter extends Filter {

            @Override
            protected FilterResults performFiltering(CharSequence prefix) {
                FilterResults results = new FilterResults();

                if (prefix == null || prefix.length() == 0) {
                    results.values = item;
                    results.count = item.length;
                } else {
                    String prefixString = prefix.toString();

                    final ArrayList<String> newValues = new ArrayList<String>();

                    for (int i = 0; i < item.length; i++) {
                        final String value = item[i];
                        if (value.equals(prefixString)) {//我这里的规则就是筛选出和prefix相同的元素
                            newValues.add(value);
                        }
                    }

                    results.values = (String[]) newValues
                            .toArray(new String[newValues.size()]);
                    results.count = newValues.size();
                }

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults results) {
                displayItem = (String[]) results.values;
                if (results.count > 0) {
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }
        }
    }

好了,接下来就可以用getFilter().filter()函数来过滤了,是不是很简单呢???

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年09月30日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.基于ArrayAdapter的过滤
  • 2.基于BaseAdapter的过滤
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档