推 tomap41017:這邊的API跟Loader沒同步蠻困擾得XD 12/29 01:01
http://tinyurl.com/borkabs
由於這篇直接從上一篇的code拿來修改 所以建議先看過上一篇
首先先在你的activity加入一個editText
EditText edt;
edt = (EditText) findViewById(R.id.EditText01);
然後記得設定ListView
listV.setTextFilterEnabled(true);
接著就像普通的搜尋那樣 建立一個TextWatcher
edt.addTextChangedListener(new TextWatcher(){
@Override
public void onTextChanged( CharSequence arg0, int arg1, int arg2, int
arg3){}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int
arg3){}
@Override
public void afterTextChanged(Editable arg0)
{
Main.this.adapter.getFilter().filter(arg0);
}
});
接著我們只要修改上一篇中寫得MyAdapter.java就可以了
原本是
public class MyAdapter extends BaseAdapter
由於我們要做filter的功能 所以需要
public class MyAdapter extends BaseAdapter implements Filterable
接著宣告
private List<Movie> mOriginalValues;
private MyFilter filter;
mOriginalValues是拿來保存你最原本傳進來的list
MyFilter這之後會講到
然後加入一個method
@Override
public Filter getFilter() {
if (filter == null){
filter = new MyFilter();
}
return filter;
}
接著就是開始本篇文章的重點了
就是MyFilter的部份
private class MyFilter extends Filter{
有兩個方法需要繼承
protected FilterResults performFiltering(CharSequence constraint)
protected void publishResults(CharSequence constraint, FilterResults results)
performFiltering是實際需要做篩選的code 好像是在不同的thread進行
publishResults則是用來把篩選結果publish出去的函式
先來看後者
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
movies = (ArrayList<Movie>)results.values;
if(results.count>0){
notifyDataSetChanged();
}
else{
notifyDataSetInvalidated();
}
}
記得嗎? movies是我們存放資料的List
而results.values就是篩選過後的結果
我們讓movies = results.values
notifyDataSetChanged之後會自動更新List
再來是
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString();
FilterResults result = new FilterResults();
if (mOriginalValues == null) {
synchronized (this) {
mOriginalValues = new ArrayList<Movie>(movies);
}
}
先判斷mOriginalValues是不是null
如果是的話把movies的值整個複製過去
第一次執行的話一定是null 所以mOriginalValues就會是一開始的值
if(constraint != null && constraint.toString().length() > 0){
ArrayList<Movie> filteredItems = new ArrayList<Movie>();
for(int i = 0, l = mOriginalValues.size(); i < l; i++){
Movie m = mOriginalValues.get(i);
if(m.getName().contains(constraint)){
filteredItems.add(m);
}
}
result.count = filteredItems.size();
result.values = filteredItems;
}else{
synchronized(this){
ArrayList<Movie> list = new ArrayList<Movie>(mOriginalValues);
result.values = list;
result.count = list.size();
}
}
return result;
先看else的部份
會執行到這邊就表示傳進來的參數(要搜尋的字串)是不合格的
所以就直接把一開始的mOriginalValues return回去
至於另一個部份就是搜尋整個mOriginalValues
看看是否包含要搜尋的字串
最值得注意的是
Movie m = mOriginalValues.get(i);
if(m.getName().contains(constraint)){
filteredItems.add(m);
}
這邊換成你自己的自訂class
比如說我有一個class叫做Userinfo 要搜尋聯絡人
那就
Userinfo u = mOriginalValues.get(i)
if(u.getName().contains(constraint)){
filteredItems.add(u)
}
總之filteredItems就是你最後要顯示的資料
完整的code在這邊 http://pastebin.com/pdPeAC7K
好處就是你剛剛寫得有關自訂的ListView的code完全不需要修改
只需要加入一些東西就可以達成搜尋的功能
參考資料:
http://blog.csdn.net/jiahui524/article/details/7802033
http://tinyurl.com/cu3pst4
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.198.74
像是內建的通訊錄那樣
有一個editText可以輸入,當你輸入a的時候
底下的list就自動跑出a開頭的聯絡人名單
對於普通的ArrayAdapter來說 這件事情非常簡單可以達成
最近研究了一下自訂的ListView如何達成這件事
跟大家分享一下心得
建議先看過普通的ListView如何做出這樣的東西再來看這篇文章