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