相信大家一定在見過手機通訊錄的一個情景就是使用在選人的時候輸入文字框裡的資料就能自動篩選。今天也受一網友邀請,所以還是整理了一下這塊的知識點,現在與大家共用一下,有什麼疑惑的可以與我交流。實現的效果如。
其實實現這樣的效果相信大家一定對另外一個控制項不陌生那就AutoCompleteTextview,看一下這個控制項的原始碼也許就能找到你需要的答案。這裡的核心就是一個Filterable。至於Filterable的介紹和做什麼用的大家就可以自行上網尋找相關知識,其中有兩個重要的方法
方法名 |
作用 |
protected FilterResults performFiltering(CharSequence prefix) |
在這個方法裡執行過濾方法 |
protected void publishResults(CharSequence constraint, FilterResults results) |
在這個方法裡發布篩選過後得到的資料同時更新Adapter更新 |
理解這點知識那麼就看核心代碼吧,這裡就是重寫BaseAdapter然後實現Filterable
public class UserAdapter extends BaseAdapter implements Filterable {private MyFilter myFilter;private List<UserInfo> userInfos;private Context context;private ArrayList<UserInfo> mOriginalValues;private final Object mLock = new Object();public UserAdapter(Context context, List<UserInfo> userInfos) {this.context = context;this.userInfos = userInfos;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn userInfos.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn userInfos.get(arg0);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = convertView;ViewHolder holder;if (view == null) {view = LayoutInflater.from(context).inflate(R.layout.list_item,null);holder = new ViewHolder();holder.tv_nick = (TextView) view.findViewById(R.id.tv_nick);holder.tv_mobile = (TextView) view.findViewById(R.id.tv_mobile);view.setTag(holder);} else {holder = (ViewHolder) view.getTag();}holder.tv_nick.setText(userInfos.get(position).getUsername());holder.tv_mobile.setText(userInfos.get(position).getPhonenum());return view;}static class ViewHolder {TextView tv_nick;TextView tv_mobile;}@Overridepublic Filter getFilter() {if (myFilter == null) {myFilter = new MyFilter();}return myFilter;}class MyFilter extends Filter {@Overrideprotected FilterResults performFiltering(CharSequence prefix) {// 持有過濾操作完成之後的資料。該資料包括過濾操作之後的資料的值以及數量。 count:數量 values包含過濾操作之後的資料的值FilterResults results = new FilterResults();if (mOriginalValues == null) {synchronized (mLock) {// 將list的使用者 集合轉換給這個未經處理資料的ArrayListmOriginalValues = new ArrayList<UserInfo>(userInfos);}}if (prefix == null || prefix.length() == 0) {synchronized (mLock) {ArrayList<UserInfo> list = new ArrayList<UserInfo>(mOriginalValues);results.values = list;results.count = list.size();}} else {// 做正式的篩選String prefixString = prefix.toString().toLowerCase();// 聲明一個臨時的集合對象 將未經處理資料賦給這個臨時變數final ArrayList<UserInfo> values = mOriginalValues;final int count = values.size();// 新的集合對象final ArrayList<UserInfo> newValues = new ArrayList<UserInfo>(count);for (int i = 0; i < count; i++) {// 如果姓名的首碼相符或者電話相符就添加到新的集合final UserInfo value = (UserInfo) values.get(i);Log.i("coder", "PinyinUtils.getAlpha(value.getUsername())"+ PinyinUtils.getAlpha(value.getUsername()));if (PinyinUtils.getAlpha(value.getUsername()).startsWith(prefixString)|| value.getPhonenum().startsWith(prefixString)||value.getUsername().startsWith(prefixString)) {newValues.add(value);}}// 然後將這個新的集合資料賦給FilterResults對象results.values = newValues;results.count = newValues.size();}return results;}@Overrideprotected void publishResults(CharSequence constraint,FilterResults results) {// 重新將與適配器相關聯的List重賦值一下userInfos = (List<UserInfo>) results.values;if (results.count > 0) {notifyDataSetChanged();} else {notifyDataSetInvalidated();}}}}
具體有看不懂的代碼可以看注釋或者加我QQ
最後再看一下是怎麼用的吧
et_filter.addTextChangedListener(new TextWatcher() {@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {adapter.getFilter().filter(et_filter.getText().toString());}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO Auto-generated method stub}@Overridepublic void afterTextChanged(Editable s) {// TODO Auto-generated method stub}});
好了這麼一樣的一個功能就如此簡單的完成了,希望能對大家有所協助了
如需轉載引用請註明出處:http://blog.csdn.net/jiahui524