listview过滤item(基于ArrayAdapter和BaseAdapter)

来源:互联网 发布:练车软件下载 编辑:程序博客网 时间:2024/06/06 06:50

1.基于ArrayAdapter的过滤

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

        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函数自己写一个,那么我们就有必要去看一下源码

    //返回过滤器    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的源码也基本看懂,那么接下来我们也来自己做一个

    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()函数来过滤了,是不是很简单呢???

0 0
原创粉丝点击