listview過濾item(基於ArrayAdapter和BaseAdapter)
阿新 • • 發佈:2019-01-25
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()函式來過濾了,是不是很簡單呢???